Refactor command line utilities

This commit is contained in:
Romain Neutron
2013-07-16 16:01:17 +02:00
parent 86e108b20f
commit 056ac28120
59 changed files with 1031 additions and 592 deletions

View File

@@ -16,9 +16,7 @@ before_script:
- sh -c 'if [ $(php -r "echo PHP_MINOR_VERSION;") -le 4 ]; then pecl install redis; fi;'
- echo 'extension="memcache.so"' > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/memcache.ini
- echo 'extension="memcached.so"' > ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/memcached.ini
- bower install
- composer self-update
- composer install --dev --prefer-source
- bin/developer dependencies:all --prefer-source
- wget http://sphinxsearch.com/files/sphinx-2.0.6-release.tar.gz
- tar xzf sphinx-2.0.6-release.tar.gz
- sh -c "cd sphinx-2.0.6-release && wget http://snowball.tartarus.org/dist/libstemmer_c.tgz && tar xzf libstemmer_c.tgz && ./configure --with-libstemmer --with-iconv --with-mysql --enable-id64 --quiet && make -j --quiet && sudo make install"

View File

@@ -10,13 +10,16 @@
*/
use Alchemy\Phrasea\CLI;
use Alchemy\Phrasea\Core\Version;
use Alchemy\Phrasea\Command\Developer\APIRoutesDumper;
use Alchemy\Phrasea\Command\Developer\Behat;
use Alchemy\Phrasea\Command\Developer\JavascriptBuilder;
use Alchemy\Phrasea\Command\Developer\BowerInstall;
use Alchemy\Phrasea\Command\Developer\ComposerInstall;
use Alchemy\Phrasea\Command\Developer\LessCompiler;
use Alchemy\Phrasea\Command\Developer\InstallAll;
use Alchemy\Phrasea\Command\Developer\JavascriptBuilder;
use Alchemy\Phrasea\Command\Developer\RegenerateSqliteDb;
use Alchemy\Phrasea\Command\Developer\RoutesDumper;
use Alchemy\Phrasea\Core\Version;
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
use Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper;
@@ -64,6 +67,9 @@ try {
$helperSet->set($helper, $name);
}
$cli->command(new InstallAll());
$cli->command(new BowerInstall());
$cli->command(new ComposerInstall());
$cli->command(new RegenerateSqliteDb());
$cli->command(new APIRoutesDumper());
$cli->command(new RoutesDumper());

View File

@@ -95,7 +95,6 @@ use Alchemy\Phrasea\Core\Provider\NotificationDelivererServiceProvider;
use Alchemy\Phrasea\Core\Provider\ORMServiceProvider;
use Alchemy\Phrasea\Core\Provider\PhraseanetServiceProvider;
use Alchemy\Phrasea\Core\Provider\PhraseaVersionServiceProvider;
use Alchemy\Phrasea\Core\Provider\PluginServiceProvider;
use Alchemy\Phrasea\Core\Provider\RegistrationServiceProvider;
use Alchemy\Phrasea\Core\Provider\SearchEngineServiceProvider;
use Alchemy\Phrasea\Core\Provider\TaskManagerServiceProvider;
@@ -254,7 +253,6 @@ class Application extends SilexApplication
$this->register(new InstallerServiceProvider());
$this->register(new PhraseanetServiceProvider());
$this->register(new PhraseaVersionServiceProvider());
$this->register(new PluginServiceProvider());
$this->register(new PHPExiftoolServiceProvider());
$this->register(new ReCaptchaServiceProvider());
$this->register(new LessCompilerServiceProvider());
@@ -413,6 +411,10 @@ class Application extends SilexApplication
$guesser->register(new AudioMimeTypeGuesser());
$guesser->register(new VideoMimeTypeGuesser());
$app['plugins.directory'] = $app->share(function () {
return realpath(__DIR__ . '/../../../plugins');
});
call_user_func(function ($app) {
require $app['plugins.directory'] . '/services.php';
}, $this);
@@ -517,7 +519,6 @@ class Application extends SilexApplication
$event->getResponse()->setCharset('UTF-8');
}
private function setupUrlGenerator()
{
$this['url_generator'] = $this->share($this->extend('url_generator', function($urlGenerator, $app) {

View File

@@ -13,6 +13,8 @@ namespace Alchemy\Phrasea;
use Alchemy\Phrasea\Command\CommandInterface;
use Symfony\Component\Console;
use Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider;
use Alchemy\Phrasea\Core\CLIProvider\ComposerSetupServiceProvider;
/**
* Phraseanet Command Line Application
@@ -46,6 +48,9 @@ class CLI extends Application
$app['swiftmailer.spooltransport']->getSpool()->flushQueue($app['swiftmailer.transport']);
});
$this->register(new PluginServiceProvider());
$this->register(new ComposerSetupServiceProvider());
$this->bindRoutes();
}

View File

@@ -28,7 +28,7 @@ abstract class AbstractCheckCommand extends Command
{
$ret = static::CHECK_OK;
foreach($this->provideRequirements() as $collection) {
foreach ($this->provideRequirements() as $collection) {
$output->writeln('');
$output->writeln($collection->getName() . ' requirements : ');

View File

@@ -11,7 +11,6 @@
namespace Alchemy\Phrasea\Command;
use Monolog\Handler\StreamHandler;
use Alchemy\Phrasea\Command\Command;
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
use Symfony\Component\Console\Input\InputInterface;

View File

@@ -0,0 +1,82 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Developer;
use Alchemy\Phrasea\Command\Command;
use Alchemy\Phrasea\Exception\InvalidArgumentException;
use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
use Alchemy\Phrasea\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption;
class BowerInstall extends Command
{
public function __construct()
{
parent::__construct('dependencies:bower');
$this
->setDescription('Install bower dependencies')
->addOption('no-dev', 'd', InputOption::VALUE_NONE, 'Do not install dev dependencies')
->addOption('attempts', 'a', InputOption::VALUE_REQUIRED, 'Number of attempts to install dependencies.', 4);
}
protected function doExecute(InputInterface $input, OutputInterface $output)
{
$bower = $this->container['driver.bower'];
$output->writeln("Using <info>".$bower->getProcessBuilderFactory()->getBinary()."</info> for driver");
$version = trim($bower->command('-v'));
if (!version_compare('1.0.0-alpha.1', $version, '<=')) {
throw new RuntimeException(sprintf(
'Bower version 1.0.0-alpha.1 is required (version %s provided), please install bower-canary : `npm install -g bower-canary`', $version
));
}
$attempts = $input->getOption('attempts');
if (0 >= $attempts) {
throw new InvalidArgumentException('Attempts number should be a positive value.');
}
$output->write("Cleaning bower cache... ");
$bower->command(array('cache', 'clean'));
$output->writeln("<info>OK</info>");
$output->write("Removing assets... ");
$this->container['filesystem']->remove($this->container['root.path'] . '/www/assets');
$output->writeln("<info>OK</info>");
$success = false;
$n = 1;
while ($attempts > 0) {
try {
$output->write("\rInstalling assets (attempt #$n)...");
$bower->command($input->getOption('no-dev') ? array('install', '--production') : 'install');
$success = true;
$output->writeln("<info>OK</info>");
break;
} catch (ExecutionFailureException $e) {
$attempts--;
$n++;
}
}
if (!$success) {
throw new RuntimeException('Unable to install bower dependencies');
}
return 0;
}
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Developer;
use Alchemy\Phrasea\Command\Command;
use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
use Alchemy\Phrasea\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption;
class ComposerInstall extends Command
{
public function __construct()
{
parent::__construct('dependencies:composer');
$this
->setDescription('Install composer dependencies')
->addOption('no-dev', 'd', InputOption::VALUE_NONE, 'Do not install dev dependencies')
->addOption('prefer-source', 'p', InputOption::VALUE_NONE, 'Use the --prefer-source composer option');
}
protected function doExecute(InputInterface $input, OutputInterface $output)
{
$composer = $this->container['driver.composer'];
$output->write("Updating composer... ");
$composer->command('self-update');
$output->writeln("<info>OK</info>");
$commands = array('install', '--optimize-autoloader');
if ($input->getOption('prefer-source')) {
$commands[] = '--prefer-source';
}
try {
if ($input->getOption('no-dev')) {
$output->write("Installing dependencies <info>without</info> developer packages ");
$composer->command(array_merge($commands, array('--no-dev')));
$output->writeln("<info>OK</info>");
} else {
$output->write("Installing dependencies <info>with</info> developer packages ");
$composer->command(array_merge($commands, array('--dev')));
$output->writeln("<info>OK</info>");
}
} catch (ExecutionFailureException $e) {
throw new RuntimeException('Unable to install bower dependencies', $e->getCode(), $e);
}
return 0;
}
}

View File

@@ -0,0 +1,43 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Developer;
use Alchemy\Phrasea\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption;
class InstallAll extends Command
{
public function __construct()
{
parent::__construct('dependencies:all');
$this
->setDescription('Install all dependencies')
->addOption('no-dev', 'd', InputOption::VALUE_NONE, 'Do not install dev dependencies')
->addOption('prefer-source', 'p', InputOption::VALUE_NONE, 'Use the --prefer-source composer option')
->addOption('attempts', 'a', InputOption::VALUE_REQUIRED, 'Number of attempts to install bower dependencies.', 4);
}
protected function doExecute(InputInterface $input, OutputInterface $output)
{
$ret = 0;
$ret += $this->container['console']->get('dependencies:bower')->execute($input, $output);
$ret += $this->container['console']->get('dependencies:composer')->execute($input, $output);
$ret += $this->container['console']->get('assets:build-javascript')->execute($input, $output);
$ret += $this->container['console']->get('assets:compile-less')->execute($input, $output);
return min($ret, 255);
}
}

View File

@@ -52,6 +52,7 @@ class JavascriptBuilder extends Command
)
);
$output->writeln('Building JavaScript assets');
foreach ($files as $target => $sources) {
$this->buildJavascript($input, $output, $target, $sources);
@@ -62,7 +63,7 @@ class JavascriptBuilder extends Command
private function buildJavascript(InputInterface $input, OutputInterface $output, $target, $sources)
{
$output->writeln("Building <info>".basename($target)."</info>");
$output->writeln("\t".basename($target));
$this->container['filesystem']->remove($target);
$process = ProcessBuilder::create(array_merge(array('cat'), $sources))->getProcess();
@@ -81,19 +82,11 @@ class JavascriptBuilder extends Command
private function buildMinifiedJavascript(InputInterface $input, OutputInterface $output, $target, $source)
{
$output->writeln("Building <info>".basename($target)."</info>");
$output->writeln("\t".basename($target));
$this->container['filesystem']->remove($target);
$process = ProcessBuilder::create(array('uglifyjs', $source, '-nc'))->getProcess();
if ($input->getOption('verbose')) {
$output->writeln("Executing ".$process->getCommandLine()."\n");
}
$process->run();
$output = $this->container['driver.uglifyjs']->command(array($source, '-nc'));
if (!$process->isSuccessFul()) {
throw new RuntimeException(sprintf('Failed to generate %s', $target));
}
file_put_contents($target, $process->getOutput());
file_put_contents($target, $output);
}
}

View File

@@ -12,7 +12,6 @@
namespace Alchemy\Phrasea\Command\Developer;
use Alchemy\Phrasea\Command\Command;
use Alchemy\Phrasea\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -33,34 +32,13 @@ class LessCompiler extends Command
*/
protected function doExecute(InputInterface $input, OutputInterface $output)
{
$copies = array(
$this->container['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings-white.png' => $this->container['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings-white.png',
$this->container['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings.png' => $this->container['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings.png',
);
foreach ($copies as $source => $target) {
foreach ($this->container['phraseanet.less-assets'] as $source => $target) {
$this->container['filesystem']->mkdir(dirname($target));
$this->container['filesystem']->copy($source, $target);
}
$files = array(
$this->container['root.path'] . '/www/skins/login/less/login.less' => $this->container['root.path'] . '/www/skins/build/login.css',
$this->container['root.path'] . '/www/skins/account/account.less' => $this->container['root.path'] . '/www/skins/build/account.css',
$this->container['root.path'] . '/www/assets/bootstrap/less/bootstrap.less' => $this->container['root.path'] . '/www/skins/build/bootstrap/css/bootstrap.css',
$this->container['root.path'] . '/www/assets/bootstrap/less/responsive.less' => $this->container['root.path'] . '/www/skins/build/bootstrap/css/bootstrap-responsive.css',
);
$output->writeln('Building Assets...');
try {
$this->container['phraseanet.less-builder']->build($files);
} catch (RuntimeException $e) {
$output->writeln(sprintf('<error>Could not build less files %s</error>', $e->getMessage()));
return 1;
}
$output->writeln('<info>Build done !</info>');
$output->writeln('Building LESS assets');
$this->container['phraseanet.less-builder']->build($this->container['phraseanet.less-mapping'], $output);
return 0;
}

View File

@@ -0,0 +1,42 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Developer\Utils;
use Alchemy\BinaryDriver\AbstractBinary;
use Alchemy\BinaryDriver\Configuration;
use Alchemy\BinaryDriver\ConfigurationInterface;
use Psr\Log\LoggerInterface;
class BowerDriver extends AbstractBinary
{
public function getName()
{
return 'bower';
}
/**
* @param array|ConfigurationInterface $conf
* @param LoggerInterface $logger
*
* @return BowerDriver
*/
public static function create($conf = array(), LoggerInterface $logger = null)
{
if (!$conf instanceof ConfigurationInterface) {
$conf = new Configuration($conf);
}
$binaries = $conf->get('bower.binaries', array('bower'));
return static::load($binaries, $logger, $conf);
}
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Developer\Utils;
use Alchemy\BinaryDriver\AbstractBinary;
use Alchemy\BinaryDriver\Configuration;
use Alchemy\BinaryDriver\ConfigurationInterface;
use Psr\Log\LoggerInterface;
class ComposerDriver extends AbstractBinary
{
public function getName()
{
return 'composer';
}
public static function create($conf = array(), LoggerInterface $logger = null)
{
if (!$conf instanceof ConfigurationInterface) {
$conf = new Configuration($conf);
}
$binaries = $conf->get('composer.binaries', array('composer'));
return static::load($binaries, $logger, $conf);
}
}

View File

@@ -0,0 +1,36 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Developer\Utils;
use Alchemy\BinaryDriver\AbstractBinary;
use Alchemy\BinaryDriver\Configuration;
use Alchemy\BinaryDriver\ConfigurationInterface;
use Psr\Log\LoggerInterface;
class UglifyJsDriver extends AbstractBinary
{
public function getName()
{
return 'uglifyjs';
}
public static function create($conf = array(), LoggerInterface $logger = null)
{
if (!$conf instanceof ConfigurationInterface) {
$conf = new Configuration($conf);
}
$binaries = $conf->get('uglifyjs.binaries', array('uglifyjs'));
return static::load($binaries, $logger, $conf);
}
}

View File

@@ -38,18 +38,8 @@ abstract class AbstractPluginCommand extends Command
$this->container['plugins.autoloader-generator']->write($manifests);
$output->writeln(" <comment>OK</comment>");
$files = array(
$this->container['root.path'] . '/www/skins/login/less/login.less' => $this->container['root.path'] . '/www/skins/build/login.css',
$this->container['root.path'] . '/www/skins/account/account.less' => $this->container['root.path'] . '/www/skins/build/account.css',
);
$output->write('Building Assets...');
try {
$this->container['phraseanet.less-builder']->build($files);
$output->writeln(" <comment>OK</comment>");
} catch (RuntimeException $e) {
$output->writeln(sprintf('<error>Could not build less files %s</error>', $e->getMessage()));
}
$output->write('Building LESS assets');
$this->container['phraseanet.less-builder']->build($this->container['phraseanet.less-mapping.customizable'], $output);
$output->writeln(" <comment>OK</comment>");
}
}

View File

@@ -35,7 +35,7 @@ class RemovePlugin extends AbstractPluginCommand
$output->writeln(" <comment>OK</comment>");
$path = $this->container['plugins.directory'] . DIRECTORY_SEPARATOR . $name;
$output->write("Removing <info>$name</info>...");
$this->container['filesystem']->remove($path);
$output->writeln(" <comment>OK</comment>");

View File

@@ -1,99 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Setup;
use Alchemy\Phrasea\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\ProcessBuilder;
use Alchemy\Phrasea\Exception\RuntimeException;
/**
* This command builds less file
*/
class JavascriptBuilder extends Command
{
public function __construct()
{
parent::__construct('assets:build-javascript');
$this->setDescription('Compile less files');
}
/**
* {@inheritdoc}
*/
protected function doExecute(InputInterface $input, OutputInterface $output)
{
$files = array(
$this->container['root.path'] . '/www/skins/build/bootstrap/js/bootstrap.js' => array(
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-transition.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-alert.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-button.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-carousel.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-collapse.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-dropdown.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-modal.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-tooltip.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-popover.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-scrollspy.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-tab.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-typeahead.js',
$this->container['root.path'] . '/www/assets/bootstrap/js/bootstrap-affix.js',
)
);
foreach ($files as $target => $sources) {
$this->buildJavascript($input, $output, $target, $sources);
$minifiedTarget = substr($target, 0, -3) . '.min.js';
$this->buildMinifiedJavascript($input, $output, $minifiedTarget, $target);
}
}
private function buildJavascript(InputInterface $input, OutputInterface $output, $target, $sources)
{
$output->writeln("Building <info>".basename($target)."</info>");
$this->container['filesystem']->remove($target);
$process = ProcessBuilder::create(array_merge(array('cat'), $sources))->getProcess();
if ($input->getOption('verbose')) {
$output->writeln("Executing ".$process->getCommandLine()."\n");
}
$process->run();
if (!$process->isSuccessFul()) {
throw new RuntimeException(sprintf('Failed to generate %s', $target));
}
$this->container['filesystem']->mkdir(dirname($target));
file_put_contents($target, $process->getOutput());
}
private function buildMinifiedJavascript(InputInterface $input, OutputInterface $output, $target, $source)
{
$output->writeln("Building <info>".basename($target)."</info>");
$this->container['filesystem']->remove($target);
$process = ProcessBuilder::create(array('uglifyjs', $source, '-nc'))->getProcess();
if ($input->getOption('verbose')) {
$output->writeln("Executing ".$process->getCommandLine()."\n");
}
$process->run();
if (!$process->isSuccessFul()) {
throw new RuntimeException(sprintf('Failed to generate %s', $target));
}
file_put_contents($target, $process->getOutput());
}
}

View File

@@ -1,95 +0,0 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Command\Setup;
use Alchemy\Phrasea\Command\Command;
use Alchemy\Phrasea\Exception\RuntimeException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\ProcessBuilder;
/**
* This command builds less file
*/
class LessCompiler extends Command
{
public function __construct()
{
parent::__construct('assets:compile-less');
$this->setDescription('Compile less files');
}
/**
* {@inheritdoc}
*/
protected function doExecute(InputInterface $input, OutputInterface $output)
{
$files = array(
$this->container['root.path'] . '/www/skins/login/less/login.less' => $this->container['root.path'] . '/www/skins/build/login.css',
$this->container['root.path'] . '/www/skins/account/account.less' => $this->container['root.path'] . '/www/skins/build/account.css',
$this->container['root.path'] . '/www/assets/bootstrap/less/bootstrap.less' => $this->container['root.path'] . '/www/skins/build/bootstrap/css/bootstrap.css',
$this->container['root.path'] . '/www/assets/bootstrap/less/responsive.less' => $this->container['root.path'] . '/www/skins/build/bootstrap/css/bootstrap-responsive.css',
);
$output->writeln('Building Assets...');
$failures = 0;
$errors = array();
foreach ($files as $lessFile => $buildFile) {
$this->container['filesystem']->mkdir(dirname($buildFile));
$output->writeln(sprintf('Building %s', basename($lessFile)));
if (!is_file($lessFile)) {
throw new RuntimeException(realpath($lessFile) . ' does not exists.');
}
if (!is_writable(dirname($buildFile))) {
throw new RuntimeException(realpath(dirname($buildFile)) . ' is not writable.');
}
$builder = ProcessBuilder::create(array(
'recess',
'--compile',
$lessFile,
));
$process = $builder->getProcess();
$process->run();
if (!$process->isSuccessful()) {
$failures++;
$errors[] = $process->getErrorOutput();
}
file_put_contents($buildFile, $process->getOutput());
}
$copies = array(
$this->container['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings-white.png' => $this->container['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings-white.png',
$this->container['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings.png' => $this->container['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings.png',
);
foreach ($copies as $source => $target) {
$this->container['filesystem']->mkdir(dirname($target));
$this->container['filesystem']->copy($source, $target);
}
if (0 === $failures) {
$output->writeln('<info>Build done !</info>');
return 0;
}
$output->writeln(sprintf('<error>%d errors occured during the build %s</error>', $failures, implode(', ', $errors)));
return 1;
}
}

View File

@@ -18,7 +18,8 @@ use Symfony\Component\Console\Output\OutputInterface;
class XSendFileConfigurationDumper extends Command
{
public function __construct($name = null) {
public function __construct($name = null)
{
parent::__construct('xsendfile:dump-configuration');
$this->setDescription('Dump the virtual host configuration depending on Phraseanet configuration');

View File

@@ -19,7 +19,6 @@ use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
class Root implements ControllerProviderInterface
{

View File

@@ -227,7 +227,7 @@ class Records implements ControllerProviderInterface
$deleted[] = $record->get_serialize_key();
$record->delete();
} catch (\Exception $e) {
}
}

View File

@@ -89,7 +89,7 @@ class Session implements ControllerProviderInterface
$session = $app['EM']->find('Entities\Session', $app['session']->get('session_id'));
$session->setUpdated(new \DateTime());
if (!$session->hasModuleId($moduleId)) {
$module = new \Entities\SessionModule();
$module->setModuleId($moduleId);

View File

@@ -0,0 +1,65 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\CLIProvider;
use Alchemy\Phrasea\Command\Developer\Utils\BowerDriver;
use Alchemy\Phrasea\Command\Developer\Utils\UglifyJsDriver;
use Alchemy\Phrasea\Command\Developer\Utils\ComposerDriver;
use Silex\Application;
use Silex\ServiceProviderInterface;
use Symfony\Component\Process\ExecutableFinder;
class CLIDriversServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['executable-finder'] = $app->share(function () {
return new ExecutableFinder();
});
$app['driver.bower'] = $app->share(function (Application $app) {
if (isset($this->container['phraseanet.configuration']['binaries']['bower_binary'])) {
$bowerBinary = $this->container['phraseanet.configuration']['binaries']['bower_binary'];
} else {
$bowerBinary = $app['executable-finder']->find('bower');
}
if (null === $bowerBinary) {
throw new RuntimeException('Unable to find bower executable.');
}
return BowerDriver::create(array('bower.binaries' => $bowerBinary), $this->container['monolog']);
});
$app['driver.composer'] = $app->share(function (Application $app) {
if (isset($this->container['phraseanet.configuration']['binaries']['composer_binary'])) {
$composerBinary = $this->container['phraseanet.configuration']['binaries']['composer_binary'];
} else {
$composerBinary = $app['executable-finder']->find('composer');
}
if (null === $composerBinary) {
throw new RuntimeException('Unable to find composer executable.');
}
return ComposerDriver::create(array('composer.binaries' => $composerBinary), $this->container['monolog']);
});
$app['driver.uglifyjs'] = $app->share(function (Application $app) {
return UglifyJsDriver::create(array(), $this->container['monolog']);
});
}
public function boot(Application $app)
{
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2013 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\CLIProvider;
use Alchemy\Phrasea\Utilities\ComposerSetup;
use Guzzle\Http\Client as Guzzle;
use Silex\Application;
use Silex\ServiceProviderInterface;
class ComposerSetupServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['composer-setup.guzzle'] = $app->share(function (Application $app) {
return new Guzzle();
});
$app['composer-setup'] = $app->share(function (Application $app) {
return new ComposerSetup($app['composer-setup.guzzle']);
});
}
public function boot(Application $app)
{
}
}

View File

@@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\Core\Provider;
namespace Alchemy\Phrasea\Core\CLIProvider;
use Alchemy\Phrasea\Plugin\Schema\ManifestValidator;
use Alchemy\Phrasea\Plugin\Management\PluginsExplorer;
@@ -20,7 +20,6 @@ use Alchemy\Phrasea\Plugin\Importer\ImportStrategy;
use Alchemy\Phrasea\Plugin\Importer\FolderImporter;
use Alchemy\Phrasea\Plugin\Management\AutoloaderGenerator;
use Alchemy\Phrasea\Plugin\Management\AssetsManager;
use Guzzle\Http\Client as Guzzle;
use JsonSchema\Validator as JsonValidator;
use Symfony\Component\Process\ExecutableFinder;
use Silex\Application;
@@ -30,7 +29,6 @@ class PluginServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['plugins.directory'] = realpath(__DIR__ . '/../../../../../plugins');
$app['plugins.schema'] = realpath(__DIR__ . '/../../../../conf.d/plugin-schema.json');
$app['plugins.json-validator'] = $app->share(function (Application $app) {
@@ -57,10 +55,6 @@ class PluginServiceProvider implements ServiceProviderInterface
return new AssetsManager($app['filesystem'], $app['plugins.directory'], $app['root.path']);
});
$app['plugins.guzzle'] = $app->share(function (Application $app) {
return new Guzzle();
});
$app['plugins.composer-installer'] = $app->share(function (Application $app) {
$binaries = $app['phraseanet.configuration']['binaries'];
$phpBinary = isset($binaries['php_binary']) ? $binaries['php_binary'] : null;
@@ -70,7 +64,7 @@ class PluginServiceProvider implements ServiceProviderInterface
$phpBinary = $finder->find('php');
}
return new ComposerInstaller($app['plugins.directory'], $app['plugins.guzzle'], $phpBinary);
return new ComposerInstaller($app['composer-setup'], $app['plugins.directory'], $phpBinary);
});
$app['plugins.explorer'] = $app->share(function (Application $app) {
return new PluginsExplorer($app['plugins.directory']);

View File

@@ -67,4 +67,3 @@ class CookiesDisablerSubscriber implements EventSubscriberInterface
}
}
}

View File

@@ -19,6 +19,34 @@ class LessBuilderServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
$app['phraseanet.less-assets'] = $app->share(function($app) {
return array(
$app['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings-white.png' => $app['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings-white.png',
$app['root.path'] . '/www/assets/bootstrap/img/glyphicons-halflings.png' => $app['root.path'] . '/www/skins/build/bootstrap/img/glyphicons-halflings.png',
);
});
$app['phraseanet.less-mapping.base'] = $app->share(function($app) {
return array(
$app['root.path'] . '/www/assets/bootstrap/less/bootstrap.less' => $app['root.path'] . '/www/skins/build/bootstrap/css/bootstrap.css',
$app['root.path'] . '/www/assets/bootstrap/less/responsive.less' => $app['root.path'] . '/www/skins/build/bootstrap/css/bootstrap-responsive.css',
);
});
$app['phraseanet.less-mapping.customizable'] = $app->share(function($app) {
return array(
$app['root.path'] . '/www/skins/login/less/login.less' => $app['root.path'] . '/www/skins/build/login.css',
$app['root.path'] . '/www/skins/account/account.less' => $app['root.path'] . '/www/skins/build/account.css',
);
});
$app['phraseanet.less-mapping'] = $app->share(function($app) {
return array_merge(
$app['phraseanet.less-mapping.base'],
$app['phraseanet.less-mapping.customizable']
);
});
$app['phraseanet.less-builder'] = $app->share(function($app) {
return new LessBuilder($app['phraseanet.less-compiler'], $app['filesystem']);
});

View File

@@ -12,28 +12,25 @@
namespace Alchemy\Phrasea\Plugin\Management;
use Alchemy\Phrasea\Plugin\Exception\ComposerInstallException;
use Alchemy\Phrasea\Utilities\ComposerSetup;
use Symfony\Component\Process\ProcessBuilder;
use Symfony\Component\Process\Exception\ExceptionInterface as ProcessException;
use Guzzle\Common\Exception\GuzzleException;
use Guzzle\Http\Client as Guzzle;
class ComposerInstaller
{
private $composer;
private $guzzle;
private $pluginsDirectory;
private $phpExecutable;
private $setup;
public function __construct($pluginsDirectory, Guzzle $guzzle, $phpExecutable)
public function __construct(ComposerSetup $setup, $pluginsDirectory, $phpExecutable)
{
if (!is_executable($phpExecutable)) {
throw new ComposerInstallException(sprintf('`%s` is not a valid PHP executable', $phpExecutable));
}
$this->guzzle = $guzzle;
$this->pluginsDirectory = $pluginsDirectory;
$this->setup = $setup;
$this->phpExecutable = $phpExecutable;
$this->composer = $this->pluginsDirectory . DIRECTORY_SEPARATOR . 'composer.phar';
$this->composer = $pluginsDirectory . DIRECTORY_SEPARATOR . 'composer.phar';
}
public function install($directory)
@@ -63,7 +60,11 @@ class ComposerInstaller
private function createProcessBuilder()
{
if (!file_exists($this->composer)) {
$this->installComposer();
try {
$this->setup->setup($this->composer);
} catch (RuntimeException $e) {
throw new ComposerInstallException('Unable to install composer.', $e->getCode(), $e);
}
} else {
$process = ProcessBuilder::create(array(
$this->phpExecutable, $this->composer, 'self-update'
@@ -73,52 +74,4 @@ class ComposerInstaller
return ProcessBuilder::create(array($this->phpExecutable, $this->composer));
}
private function installComposer()
{
$installer = $this->pluginsDirectory . DIRECTORY_SEPARATOR . 'installer';
$handle = fopen($installer, 'w+');
$request = $this->guzzle->get('https://getcomposer.org/installer', null, $handle);
try {
$response = $request->send();
fclose($handle);
} catch (GuzzleException $e) {
fclose($handle);
throw new ComposerInstallException('Unable to download composer install script.');
}
if (200 !== $response->getStatusCode()) {
@unlink($installer);
throw new ComposerInstallException('Unable to download composer install script.');
}
$dir = getcwd();
if (!@chdir($this->pluginsDirectory)) {
throw new ComposerInstallException('Unable to move to plugins directory for composer install.');
}
$process = ProcessBuilder::create(array($this->phpExecutable, $installer))->getProcess();
try {
$process->run();
@unlink($installer);
} catch (ProcessException $e) {
@unlink($installer);
throw new ComposerInstallException('Unable run composer install script.');
}
if (!@chdir($dir)) {
throw new ComposerInstallException('Unable to move to plugins directory for composer install.');
}
if (!$process->isSuccessful()) {
throw new ComposerInstallException('Composer install failed.');
}
if (!file_exists($this->composer)) {
throw new ComposerInstallException('Composer install failed.');
}
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace Alchemy\Phrasea\Utilities;
use Alchemy\Phrasea\Exception\RuntimeException;
use Guzzle\Common\Exception\GuzzleException;
use Guzzle\Http\Client as Guzzle;
use Symfony\Component\Process\ProcessBuilder;
use Symfony\Component\Process\Exception\ExceptionInterface as ProcessException;
use Symfony\Component\Process\PhpExecutableFinder;
class ComposerSetup
{
private $guzzle;
private $phpExecutable;
public function __construct(Guzzle $guzzle, $phpExecutable = null)
{
if (null === $phpExecutable) {
$finder = new PhpExecutableFinder();
$phpExecutable = $finder->find();
}
if (!is_executable($phpExecutable)) {
throw new RuntimeException(sprintf('`%s` is not a valid PHP executable', $phpExecutable));
}
$this->guzzle = $guzzle;
$this->phpExecutable = $phpExecutable;
}
/**
* Downloads composer installer and setups it to the given target.
*
* @param string $target
*
* @throws RuntimeException
*/
public function setup($target)
{
$installer = tempnam(sys_get_temp_dir(), 'install');
$handle = fopen($installer, 'w+');
$request = $this->guzzle->get('https://getcomposer.org/installer', null, $handle);
try {
$response = $request->send();
fclose($handle);
} catch (GuzzleException $e) {
fclose($handle);
throw new RuntimeException('Unable to download composer install script.');
}
if (200 !== $response->getStatusCode()) {
@unlink($installer);
throw new RuntimeException('Unable to download composer install script.');
}
$dir = getcwd();
if (!@chdir(dirname($target))) {
throw new RuntimeException('Unable to move to target directory for composer install.');
}
$process = ProcessBuilder::create(array($this->phpExecutable, $installer))->getProcess();
try {
$process->run();
@unlink($installer);
} catch (ProcessException $e) {
@unlink($installer);
throw new RuntimeException('Unable run composer install script.');
}
if (!@rename(getcwd() . '/composer.phar', $target)) {
throw new RuntimeException('Composer install failed.');
}
if (!@chdir($dir)) {
throw new RuntimeException('Unable to move back to origin directory.');
}
if (!$process->isSuccessful()) {
throw new RuntimeException('Composer install failed.');
}
if (!file_exists($target)) {
throw new RuntimeException('Composer install failed.');
}
}
}

View File

@@ -12,6 +12,7 @@
namespace Alchemy\Phrasea\Utilities\Less;
use Alchemy\Phrasea\Utilities\Less\Compiler as LessCompiler;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
class Builder
@@ -38,10 +39,13 @@ class Builder
*
* @throws RuntimeException
*/
public function build($files)
public function build($files, OutputInterface $output = null)
{
foreach ($files as $lessFile => $target) {
$this->filesystem->mkdir(dirname($target));
if (null !== $output) {
$output->writeln("\t".basename($target));
}
$this->compiler->compile($target, $lessFile);
}
}

View File

@@ -53,7 +53,7 @@ class Compiler
$files = (array) $files;
foreach($files as $file) {
foreach ($files as $file) {
if (false === is_file($file)) {
throw new RuntimeException($file . ' does not exists.');
}

View File

@@ -12,7 +12,7 @@ class CheckConfigTest extends \PhraseanetPHPUnitAbstract
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
$command = new CheckConfig('check:config');
$command->setContainer(self::$DI['app']);
$command->setContainer(self::$DI['cli']);
$this->assertLessThan(2, $command->execute($input, $output));
}
}

View File

@@ -9,10 +9,10 @@ class ConfigurationTest extends \PhraseanetPHPUnitAbstract
public function testExecute()
{
$command = new Configuration();
$command->setContainer(self::$DI['app']);
$command->setContainer(self::$DI['cli']);
self::$DI['app']['phraseanet.configuration'] = $this->getMock('Alchemy\Phrasea\Core\Configuration\ConfigurationInterface');
self::$DI['app']['phraseanet.configuration']->expects($this->once())
self::$DI['cli']['phraseanet.configuration'] = $this->getMock('Alchemy\Phrasea\Core\Configuration\ConfigurationInterface');
self::$DI['cli']['phraseanet.configuration']->expects($this->once())
->method('compileAndWrite');
$input = $this->getMock('Symfony\Component\Console\Input\InputInterface');

View File

@@ -0,0 +1,73 @@
<?php
namespace Alchemy\Tests\Phrasea\Command\Developper;
use Alchemy\Phrasea\Command\Developer\BowerInstall;
class BowerInstallTest extends \PhraseanetPHPUnitAbstract
{
public function testRunWithoutProblems()
{
$input = $this->getMock('Symfony\Component\Console\Input\InputInterface');
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
$input->expects($this->any())
->method('getOption')
->will($this->returnCallback(function ($name) {
switch ($name) {
case 'attempts':
return 4;
default:
return null;
}
}));
$input->expects($this->any())
->method('getArgument')
->will($this->returnCallback(function ($name) {
switch ($name) {
default:
return null;
}
}));
self::$DI['cli']['filesystem'] = $this->getMockBuilder('Symfony\Component\Filesystem\Filesystem')
->disableOriginalConstructor()
->getMock();
self::$DI['cli']['filesystem']->expects($this->once())
->method('remove')
->with(self::$DI['cli']['root.path'].'/www/assets');
self::$DI['cli']['driver.bower'] = $this->getMockBuilder('Alchemy\Phrasea\Command\Developer\Utils\BowerDriver')
->disableOriginalConstructor()
->getMock();
$processBuilder = $this->getMock('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface');
$processBuilder->expects($this->once())
->method('getBinary')
->will($this->returnValue('/opt/local/bin/bower'));
self::$DI['cli']['driver.bower']->expects($this->at(0))
->method('getProcessBuilderFactory')
->will($this->returnValue($processBuilder));
self::$DI['cli']['driver.bower']->expects($this->at(1))
->method('command')
->with('-v')
->will($this->returnValue('1.0.0-alpha.5'));
self::$DI['cli']['driver.bower']->expects($this->at(2))
->method('command')
->with(array('cache', 'clean'));
self::$DI['cli']['driver.bower']->expects($this->at(3))
->method('command')
->with('install');
$command = new BowerInstall();
$command->setContainer(self::$DI['cli']);
$this->assertEquals(0, $command->execute($input, $output));
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Alchemy\Tests\Phrasea\Command\Developper;
use Alchemy\Phrasea\Command\Developer\ComposerInstall;
class BowerInstallTest extends \PhraseanetPHPUnitAbstract
{
public function testRunWithoutProblems()
{
$input = $this->getMock('Symfony\Component\Console\Input\InputInterface');
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
self::$DI['cli']['driver.composer'] = $this->getMockBuilder('Alchemy\Phrasea\Command\Developer\Utils\ComposerDriver')
->disableOriginalConstructor()
->getMock();
self::$DI['cli']['driver.composer']->expects($this->at(0))
->method('command')
->with('self-update');
self::$DI['cli']['driver.composer']->expects($this->at(1))
->method('command')
->with(array('install', '--optimize-autoloader', '--dev'));
$command = new ComposerInstall();
$command->setContainer(self::$DI['cli']);
$this->assertEquals(0, $command->execute($input, $output));
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Alchemy\Tests\Phrasea\Command\Developper;
use Alchemy\Phrasea\Command\Developer\InstallAll;
class InstallAllTest extends \PhraseanetPHPUnitAbstract
{
public function testRunWithoutProblems()
{
$input = $this->getMock('Symfony\Component\Console\Input\InputInterface');
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
self::$DI['cli']['console'] = $this->getMockBuilder('Symfony\Component\Console\Application')
->disableOriginalConstructor()
->getMock();
$n = 0;
foreach (array(
'dependencies:bower',
'dependencies:composer',
'assets:build-javascript',
'assets:compile-less',
) as $name) {
$command = $this->getMockBuilder('Symfony\Component\Console\Command\Command')
->setMethods(array('execute'))
->disableOriginalConstructor()
->getMock();
$command->expects($this->once())
->method('execute')
->with($input, $output)
->will($this->returnValue(0));
self::$DI['cli']['console']->expects($this->at($n))
->method('get')
->with($name)
->will($this->returnValue($command));
$n++;
}
$command = new InstallAll();
$command->setContainer(self::$DI['cli']);
$this->assertEquals(0, $command->execute($input, $output));
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Alchemy\Tests\Phrasea\Command\Developper\Utils;
use Alchemy\Phrasea\Command\Developer\Utils\BowerDriver;
use Symfony\Component\Process\PhpExecutableFinder;
class BowerDriverTest extends \PHPUnit_Framework_TestCase
{
public function testCreate()
{
$driver = BowerDriver::create();
$this->assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\BowerDriver', $driver);
$this->assertEquals('bower', $driver->getName());
}
public function testCreateWithCustomBinary()
{
$finder = new PhpExecutableFinder();
$php = $finder->find();
$driver = BowerDriver::create(array('bower.binaries' => $php));
$this->assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\BowerDriver', $driver);
$this->assertEquals($php, $driver->getProcessBuilderFactory()->getBinary());
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Alchemy\Tests\Phrasea\Command\Developper\Utils;
use Alchemy\Phrasea\Command\Developer\Utils\ComposerDriver;
use Symfony\Component\Process\PhpExecutableFinder;
class ComposerDriverTest extends \PHPUnit_Framework_TestCase
{
public function testCreate()
{
$driver = ComposerDriver::create();
$this->assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\ComposerDriver', $driver);
$this->assertEquals('composer', $driver->getName());
}
public function testCreateWithCustomBinary()
{
$finder = new PhpExecutableFinder();
$php = $finder->find();
$driver = ComposerDriver::create(array('composer.binaries' => $php));
$this->assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\ComposerDriver', $driver);
$this->assertEquals($php, $driver->getProcessBuilderFactory()->getBinary());
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace Alchemy\Tests\Phrasea\Command\Developper\Utils;
use Alchemy\Phrasea\Command\Developer\Utils\UglifyJsDriver;
use Symfony\Component\Process\PhpExecutableFinder;
class UglifyJsDriverTest extends \PHPUnit_Framework_TestCase
{
public function testCreate()
{
$driver = UglifyJsDriver::create();
$this->assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\UglifyJsDriver', $driver);
$this->assertEquals('uglifyjs', $driver->getName());
}
public function testCreateWithCustomBinary()
{
$finder = new PhpExecutableFinder();
$php = $finder->find();
$driver = UglifyJsDriver::create(array('uglifyjs.binaries' => $php));
$this->assertInstanceOf('Alchemy\Phrasea\Command\Developer\Utils\UglifyJsDriver', $driver);
$this->assertEquals($php, $driver->getProcessBuilderFactory()->getBinary());
}
}

View File

@@ -18,11 +18,11 @@ class MailTestTest extends \PhraseanetPHPUnitAbstract
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
self::$DI['app']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer')
self::$DI['cli']['notification.deliverer'] = $this->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer')
->disableOriginalConstructor()
->getMock();
self::$DI['app']['notification.deliverer']->expects($this->once())
self::$DI['cli']['notification.deliverer']->expects($this->once())
->method('deliver')
->with($this->isInstanceOf('Alchemy\Phrasea\Notification\Mail\MailTest'), $this->equalTo(null))
->will($this->returnCallback(function ($email) use (&$capturedEmail) {
@@ -30,7 +30,7 @@ class MailTestTest extends \PhraseanetPHPUnitAbstract
}));
$command = new MailTest('mail:test');
$command->setContainer(self::$DI['app']);
$command->setContainer(self::$DI['cli']);
$result = $command->execute($input, $output);
$this->assertSame(0, $result);

View File

@@ -19,57 +19,57 @@ class AddPluginTest extends PluginCommandTestCase
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
$command = new AddPlugin();
$command->setContainer(self::$DI['app']);
$command->setContainer(self::$DI['cli']);
$manifest = $this->createManifestMock();
$manifest->expects($this->any())
->method('getName')
->will($this->returnValue($source));
self::$DI['app']['temporary-filesystem'] = $this->createTemporaryFilesystemMock();
self::$DI['app']['plugins.autoloader-generator'] = $this->createPluginsAutoloaderGeneratorMock();
self::$DI['app']['plugins.explorer'] = array(self::$DI['app']['plugins.directory'].'/TestPlugin');
self::$DI['app']['plugins.plugins-validator'] = $this->createPluginsValidatorMock();
self::$DI['app']['filesystem'] = $this->createFilesystemMock();
self::$DI['app']['plugins.composer-installer'] = $this->createComposerInstallerMock();
self::$DI['app']['plugins.importer'] = $this->createPluginsImporterMock();
self::$DI['cli']['temporary-filesystem'] = $this->createTemporaryFilesystemMock();
self::$DI['cli']['plugins.autoloader-generator'] = $this->createPluginsAutoloaderGeneratorMock();
self::$DI['cli']['plugins.explorer'] = array(self::$DI['cli']['plugins.directory'].'/TestPlugin');
self::$DI['cli']['plugins.plugins-validator'] = $this->createPluginsValidatorMock();
self::$DI['cli']['filesystem'] = $this->createFilesystemMock();
self::$DI['cli']['plugins.composer-installer'] = $this->createComposerInstallerMock();
self::$DI['cli']['plugins.importer'] = $this->createPluginsImporterMock();
self::$DI['app']['temporary-filesystem']->expects($this->once())
self::$DI['cli']['temporary-filesystem']->expects($this->once())
->method('createTemporaryDirectory')
->will($this->returnValue('tempdir'));
self::$DI['app']['plugins.importer']->expects($this->once())
self::$DI['cli']['plugins.importer']->expects($this->once())
->method('import')
->with($source, 'tempdir');
// the plugin is checked when updating config files
self::$DI['app']['plugins.plugins-validator']->expects($this->at(0))
self::$DI['cli']['plugins.plugins-validator']->expects($this->at(0))
->method('validatePlugin')
->with('tempdir')
->will($this->returnValue($manifest));
self::$DI['app']['plugins.plugins-validator']->expects($this->at(1))
self::$DI['cli']['plugins.plugins-validator']->expects($this->at(1))
->method('validatePlugin')
->with(self::$DI['app']['plugins.directory'].'/TestPlugin')
->with(self::$DI['cli']['plugins.directory'].'/TestPlugin')
->will($this->returnValue($manifest));
self::$DI['app']['plugins.composer-installer']->expects($this->once())
self::$DI['cli']['plugins.composer-installer']->expects($this->once())
->method('install')
->with('tempdir');
self::$DI['app']['filesystem']->expects($this->at(0))
self::$DI['cli']['filesystem']->expects($this->at(0))
->method('mirror')
->with('tempdir', self::$DI['app']['plugins.directory'].'/TestPlugin');
->with('tempdir', self::$DI['cli']['plugins.directory'].'/TestPlugin');
self::$DI['app']['filesystem']->expects($this->at(1))
self::$DI['cli']['filesystem']->expects($this->at(1))
->method('mirror')
->with(self::$DI['app']['plugins.directory'].'/TestPlugin/public', self::$DI['app']['root.path'].'/www/plugins/TestPlugin');
->with(self::$DI['cli']['plugins.directory'].'/TestPlugin/public', self::$DI['cli']['root.path'].'/www/plugins/TestPlugin');
self::$DI['app']['filesystem']->expects($this->at(2))
self::$DI['cli']['filesystem']->expects($this->at(2))
->method('remove')
->with('tempdir');
self::$DI['app']['plugins.autoloader-generator']->expects($this->once())
self::$DI['cli']['plugins.autoloader-generator']->expects($this->once())
->method('write')
->with(array($manifest));

View File

@@ -19,16 +19,16 @@ class RemovePluginTest extends PluginCommandTestCase
$output = $this->getMock('Symfony\Component\Console\Output\OutputInterface');
$command = new RemovePlugin();
$command->setContainer(self::$DI['app']);
$command->setContainer(self::$DI['cli']);
self::$DI['app']['filesystem'] = $this->createFilesystemMock();
self::$DI['app']['filesystem']->expects($this->at(0))
self::$DI['cli']['filesystem'] = $this->createFilesystemMock();
self::$DI['cli']['filesystem']->expects($this->at(0))
->method('remove')
->with(self::$DI['app']['root.path'].'/www/plugins/'.$name);
->with(self::$DI['cli']['root.path'].'/www/plugins/'.$name);
self::$DI['app']['filesystem']->expects($this->at(1))
self::$DI['cli']['filesystem']->expects($this->at(1))
->method('remove')
->with(self::$DI['app']['plugins.directory'].'/'.$name);
->with(self::$DI['cli']['plugins.directory'].'/'.$name);
$result = $command->execute($input, $output);

View File

@@ -78,17 +78,17 @@ class InstallTest extends \PhraseanetPHPUnitAbstract
}
}));
self::$DI['app']['phraseanet.installer'] = $this->getMockBuilder('Alchemy\Phrasea\Setup\Installer')
self::$DI['cli']['phraseanet.installer'] = $this->getMockBuilder('Alchemy\Phrasea\Setup\Installer')
->disableOriginalConstructor()
->getMock();
self::$DI['app']['phraseanet.installer']->expects($this->once())
self::$DI['cli']['phraseanet.installer']->expects($this->once())
->method('install')
->with($email, $password, $this->isInstanceOf('\connection_interface'), $serverName, $dataPath, $this->isInstanceOf('\connection_interface'), $template, $this->anything());
$command = new Install('system:check');
$command->setHelperSet($helperSet);
$command->setContainer(self::$DI['app']);
$command->setContainer(self::$DI['cli']);
$this->assertEquals(0, $command->execute($input, $output));
}
}

View File

@@ -27,19 +27,19 @@ class XSendFileMappingGeneratorTest extends \PhraseanetPHPUnitAbstract
$command = new XSendFileMappingGenerator();
$phpunit = $this;
self::$DI['app']['monolog'] = self::$DI['app']->share(function () use ($phpunit) {
self::$DI['cli']['monolog'] = self::$DI['cli']->share(function () use ($phpunit) {
return $phpunit->getMockBuilder('Monolog\Logger')->disableOriginalConstructor()->getMock();
});
self::$DI['app']['phraseanet.configuration'] = $this->getMock('Alchemy\Phrasea\Core\Configuration\ConfigurationInterface');
self::$DI['cli']['phraseanet.configuration'] = $this->getMock('Alchemy\Phrasea\Core\Configuration\ConfigurationInterface');
if ($option) {
self::$DI['app']['phraseanet.configuration']->expects($this->once())
self::$DI['cli']['phraseanet.configuration']->expects($this->once())
->method('offsetSet')
->with('xsendfile');
} else {
self::$DI['app']['phraseanet.configuration']->expects($this->never())
self::$DI['cli']['phraseanet.configuration']->expects($this->never())
->method('offsetSet');
}
$command->setContainer(self::$DI['app']);
$command->setContainer(self::$DI['cli']);
$this->assertEquals(0, $command->execute($input, $output));
}
@@ -55,7 +55,7 @@ class XSendFileMappingGeneratorTest extends \PhraseanetPHPUnitAbstract
->will($this->returnValue(null));
$command = new XSendFileMappingGenerator();
$command->setContainer(self::$DI['app']);
$command->setContainer(self::$DI['cli']);
$this->setExpectedException('Alchemy\Phrasea\Exception\InvalidArgumentException');
$command->execute($input, $output);
}

View File

@@ -456,7 +456,6 @@ class LoginTest extends \PhraseanetWebTestCaseAuthenticatedAbstract
$crawler = self::$DI['client']->request('GET', '/login/register-classic/?providerId=provider-test');
echo self::$DI['client']->getResponse();
$this->assertEquals(200, self::$DI['client']->getResponse()->getStatusCode());
$this->assertEquals(1, $crawler->filterXPath("//input[@value='supermail@superprovider.com' and @name='email']")->count());
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\CLIProvider;
/**
* @covers Alchemy\Phrasea\Core\CLIProvider\CLIDriversServiceProvider
*/
class CLISDriversServiceProviderTest extends ServiceProviderTestCase
{
public function provideServiceDescription()
{
return array(
array(
'Alchemy\Phrasea\Core\CLIProvider\CLIDriversServiceProvider',
'executable-finder',
'Symfony\Component\Process\ExecutableFinder'
),
array(
'Alchemy\Phrasea\Core\CLIProvider\CLIDriversServiceProvider',
'driver.bower',
'Alchemy\Phrasea\Command\Developer\Utils\BowerDriver'
),
array(
'Alchemy\Phrasea\Core\CLIProvider\CLIDriversServiceProvider',
'driver.composer',
'Alchemy\Phrasea\Command\Developer\Utils\ComposerDriver'
),
array(
'Alchemy\Phrasea\Core\CLIProvider\CLIDriversServiceProvider',
'driver.uglifyjs',
'Alchemy\Phrasea\Command\Developer\Utils\UglifyJsDriver'
),
);
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\CLIProvider;
/**
* @covers Alchemy\Phrasea\Core\CLIProvider\ComposerSetupServiceProvider
*/
class ComposerSetupServiceProvidertest extends ServiceProviderTestCase
{
public function provideServiceDescription()
{
return array(
array(
'Alchemy\Phrasea\Core\CLIProvider\ComposerSetupServiceProvider',
'composer-setup',
'Alchemy\Phrasea\Utilities\ComposerSetup'
),
);
}
}

View File

@@ -1,13 +1,12 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\Provider;
namespace Alchemy\Tests\Phrasea\Core\CLIProvider;
use Alchemy\Phrasea\Core\Provider\PluginServiceProvider;
use Silex\Application;
use Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider;
use Symfony\Component\Process\ExecutableFinder;
/**
* @covers Alchemy\Phrasea\Core\Provider\PluginServiceProvider
* @covers Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider
*/
class PluginServiceProvidertest extends ServiceProviderTestCase
{
@@ -15,57 +14,52 @@ class PluginServiceProvidertest extends ServiceProviderTestCase
{
return array(
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
'plugins.json-validator',
'JsonSchema\Validator'
),
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
'plugins.plugins-validator',
'Alchemy\Phrasea\Plugin\Schema\PluginValidator'
),
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
'plugins.manifest-validator',
'Alchemy\Phrasea\Plugin\Schema\ManifestValidator'
),
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
'plugins.import-strategy',
'Alchemy\Phrasea\Plugin\Importer\ImportStrategy'
),
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
'plugins.autoloader-generator',
'Alchemy\Phrasea\Plugin\Management\AutoloaderGenerator'
),
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'plugins.guzzle',
'Guzzle\Http\Client'
),
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
'plugins.composer-installer',
'Alchemy\Phrasea\Plugin\Management\ComposerInstaller'
),
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
'plugins.explorer',
'Alchemy\Phrasea\Plugin\Management\PluginsExplorer'
),
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
'plugins.importer',
'Alchemy\Phrasea\Plugin\Importer\Importer'
),
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
'plugins.importer.folder-importer',
'Alchemy\Phrasea\Plugin\Importer\FolderImporter'
),
array(
'Alchemy\Phrasea\Core\Provider\PluginServiceProvider',
'Alchemy\Phrasea\Core\CLIProvider\PluginServiceProvider',
'plugins.assets-manager',
'Alchemy\Phrasea\Plugin\Management\AssetsManager'
)
@@ -74,7 +68,7 @@ class PluginServiceProvidertest extends ServiceProviderTestCase
public function testSchemaIsDefined()
{
$app = new Application();
$app = self::$DI['cli'];
$app->register(new PluginServiceProvider());
$this->assertFileExists($app['plugins.schema']);
@@ -83,7 +77,7 @@ class PluginServiceProvidertest extends ServiceProviderTestCase
public function testPluginDirIsDefined()
{
$app = new Application();
$app = self::$DI['cli'];
$app->register(new PluginServiceProvider());
$this->assertFileExists($app['plugins.directory']);
@@ -99,7 +93,7 @@ class PluginServiceProvidertest extends ServiceProviderTestCase
$this->markTestSkipped('Unable to detect PHP binary');
}
$app = new Application();
$app = self::$DI['cli'];
$app['phraseanet.configuration'] = array('binaries' => array('php_binary' => null));
$app->register(new PluginServiceProvider());
$this->assertInstanceOf('Alchemy\Phrasea\Plugin\Management\ComposerInstaller', $app['plugins.composer-installer']);
@@ -107,7 +101,7 @@ class PluginServiceProvidertest extends ServiceProviderTestCase
public function testInstallerCanDetectPhpConf()
{
$app = new Application();
$app = self::$DI['cli'];
$app['phraseanet.configuration'] = array('binaries' => array('php_binary' => null));
$app->register(new PluginServiceProvider());
$this->assertInstanceOf('Alchemy\Phrasea\Plugin\Management\ComposerInstaller', $app['plugins.composer-installer']);

View File

@@ -0,0 +1,24 @@
<?php
namespace Alchemy\Tests\Phrasea\Core\CLIProvider;
abstract class ServiceProviderTestCase extends \PhraseanetPHPUnitAbstract
{
/**
* @test
* @dataProvider provideServiceDescription
*/
public function theSameInstanceShouldBereturnedEveryTime($service, $key, $classname)
{
$cli = self::$DI['cli'];
$cli->register(new $service());
$instance1 = $cli[$key];
$instance2 = $cli[$key];
$this->assertInstanceof($classname, $instance1);
$this->assertEquals($instance1, $instance2);
}
abstract public function provideServiceDescription();
}

View File

@@ -4,7 +4,6 @@ namespace Alchemy\Tests\Phrasea\Core\Provider;
use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider;
use Alchemy\Phrasea\Core\Provider\FileServeServiceProvider;
use Silex\Application;
/**
* @covers Alchemy\Phrasea\Core\Provider\FileServeServiceProvider

View File

@@ -12,7 +12,7 @@ class CustomCommand extends Command
{
parent::__construct('hello:world');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->write('Hello World');

View File

@@ -3,6 +3,7 @@
namespace Alchemy\Phrasea\Plugin\Management;
use Alchemy\Phrasea\Plugin\Management\ComposerInstaller;
use Alchemy\Phrasea\Utilities\ComposerSetup;
use Guzzle\Http\Client as Guzzle;
use Symfony\Component\Process\ExecutableFinder;
use Symfony\Component\Filesystem\Filesystem;
@@ -26,7 +27,11 @@ class ComposerInstallerTest extends \PHPUnit_Framework_TestCase
$this->markTestSkipped('Unable to find PHP executable.');
}
$installer = new ComposerInstaller(__DIR__, new Guzzle(), $php);
$setupMock = $this->getMockBuilder('Alchemy\Phrasea\Utilities\ComposerSetup')
->disableOriginalConstructor()
->getMock();
$installer = new ComposerInstaller(new ComposerSetup(new Guzzle()), __DIR__, $php);
$installer->install(__DIR__ . '/../Fixtures/PluginDir/TestPlugin');
$this->assertFileExists($composer);

View File

@@ -8,7 +8,7 @@ class PluginTestCase extends \PhraseanetPHPUnitAbstract
{
protected function createManifestValidator()
{
return ManifestValidator::create(self::$DI['app']);
return ManifestValidator::create(self::$DI['cli']);
}
protected function getPluginDirectory()

View File

@@ -62,12 +62,12 @@ class ManifestValidatorTest extends PluginTestCase
*/
public function testConstructWithInvalidSchema()
{
new ManifestValidator(new JsonSchemaValidator(), array(), self::$DI['app']['phraseanet.version']);
new ManifestValidator(new JsonSchemaValidator(), array(), self::$DI['cli']['phraseanet.version']);
}
public function testCreate()
{
$validator = ManifestValidator::create(self::$DI['app']);
$validator = ManifestValidator::create(self::$DI['cli']);
$this->assertInstanceOf('Alchemy\Phrasea\Plugin\Schema\ManifestValidator', $validator);
}
@@ -76,6 +76,6 @@ class ManifestValidatorTest extends PluginTestCase
{
$schema = json_decode($this->getSchema());
return new ManifestValidator(new JsonSchemaValidator(), $schema, self::$DI['app']['phraseanet.version']);
return new ManifestValidator(new JsonSchemaValidator(), $schema, self::$DI['cli']['phraseanet.version']);
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Alchemy\Tests\Phrasea\Utilities;
use Alchemy\Phrasea\Utilities\ComposerSetup;
use Guzzle\Http\Client as Guzzle;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\ProcessBuilder;
class ComposerSetupTest extends \PHPUnit_Framework_TestCase
{
public function testSetup()
{
$target = __DIR__ . '/target-composer';
if (is_file($target)) {
unlink($target);
}
$setup = new ComposerSetup(new Guzzle());
$setup->setup($target);
$finder = new PhpExecutableFinder();
$php = $finder->find();
$process = ProcessBuilder::create(array($php, $target, '--version'))->getProcess();
$process->run();
$this->assertTrue($process->isSuccessful());
$this->assertSame(0, strpos($process->getOutput(), 'Composer version'));
unlink($target);
}
}

View File

@@ -1,5 +1,6 @@
<?php
use Alchemy\Phrasea\CLI;
use Alchemy\Phrasea\Application;
use Alchemy\Phrasea\Border\File;
use Doctrine\Common\DataFixtures\Loader;
@@ -154,6 +155,48 @@ abstract class PhraseanetPHPUnitAbstract extends WebTestCase
return $app;
});
self::$DI['cli'] = self::$DI->share(function($DI) use ($phpunit) {
$app = new CLI('cli test', null, 'test');
$app['form.csrf_provider'] = $app->share(function () {
return new CsrfTestProvider();
});
$app['url_generator'] = $app->share($app->extend('url_generator', function($generator, $app) {
$host = parse_url($app['phraseanet.configuration']['main']['servername'], PHP_URL_HOST);
$generator->setContext(new RequestContext('', 'GET', $host));
return $generator;
}));
$app['debug'] = true;
$app['EM'] = $app->share($app->extend('EM', function($em) {
@unlink('/tmp/db.sqlite');
copy(__DIR__ . '/../db-ref.sqlite', '/tmp/db.sqlite');
return $em;
}));
$app['browser'] = $app->share($app->extend('browser', function($browser) {
$browser->setUserAgent(PhraseanetPHPUnitAbstract::USER_AGENT_FIREFOX8MAC);
return $browser;
}));
$app['notification.deliverer'] = $phpunit->getMockBuilder('Alchemy\Phrasea\Notification\Deliverer')
->disableOriginalConstructor()
->getMock();
$app['notification.deliverer']->expects($phpunit->any())
->method('deliver')
->will($phpunit->returnCallback(function() use ($phpunit) {
$phpunit->fail('Notification deliverer must be mocked');
}));
return $app;
});
self::$DI['client'] = self::$DI->share(function($DI) {
return new Client($DI['app'], array());
});

View File

@@ -46,9 +46,9 @@ class recordutils_imageTest extends PhraseanetPHPUnitAbstract
$prefs = '<?xml version="1.0" encoding="UTF-8"?>
<baseprefs>
<status>0</status>
<status>0</status>
<stamp>
<stamp>
<logo position="left" width="25%"/>
<text size="50%">Date: <var name="date"/></text>
<text size="50%">Record_id: <var name="record_id"/></text>';
@@ -59,9 +59,9 @@ class recordutils_imageTest extends PhraseanetPHPUnitAbstract
}
$prefs .= '</stamp>
<caninscript>1</caninscript>
<sugestedValues>
</sugestedValues>
<caninscript>1</caninscript>
<sugestedValues>
</sugestedValues>
</baseprefs>';
$newdom = new DOMDocument();
@@ -105,4 +105,4 @@ class recordutils_imageTest extends PhraseanetPHPUnitAbstract
$this->assertTrue(0 === strpos(basename($path), 'stamp_'));
unlink($path);
}
}
}

View File

@@ -1,137 +0,0 @@
#!/usr/bin/env php
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Get all dependencies needed for Phraseanet
*/
chdir(__DIR__);
set_time_limit(0);
$bower = 'bower';
$node = 'node';
$recess = 'recess';
$uglifyjs = 'uglifyjs';
$npm = 'npm';
// Test if node exists
exec(sprintf('%s -v', $node), $output, $code);
if (0 !== $code) {
echo sprintf('%s is required to install vendors', $node);
exit(1);
}
// Test if npm exists
exec(sprintf('%s -v', $npm), $output, $code);
if (0 !== $code) {
echo sprintf('%s is required to install vendors', $npm),
exit(1);
}
// Test if bower exists else install it
exec(sprintf('%s -v', $bower), $output, $code);
if (0 !== $code) {
exec(sprintf('sudo %s install %s -g', $npm, $bower), $output, $code);
if (0 !== $code) {
echo sprintf('Failed to install %s', $bower);
exit(1);
}
}
// Tests if recess exists else install it
exec(sprintf('%s -v', $recess), $output, $code);
if (0 !== $code) {
exec(sprintf('sudo %s install %s -g', $npm, $recess), $output, $code);
if (0 !== $code) {
echo sprintf('Failed to install %s', $recess);
exit(1);
}
}
// Tests if recess exists else install it
exec('uglifyjs --version', $output, $code);
if (0 !== $code) {
exec(sprintf('sudo %s install uglify-js -g', $npm), $output, $code);
if (0 !== $code) {
echo 'Failed to install uglifyjs';
exit(1);
}
}
// Remove previous assets
$assetDir = __DIR__. '/www/assets';
$code = 0;
if (is_dir($assetDir)) {
system('rm -r ' . escapeshellarg($assetDir), $code);
}
if (0 !== $code) {
echo sprintf('Warning, failed to remove previous %s dependencies in %s', $bower, $assetDir);
echo "\n";
}
// Clean bower cache
system(sprintf('%s cache-clean', $bower), $code);
if (0 !== $code) {
echo sprintf('Warning, failed to clean %s cache', $bower);
echo "\n";
}
// Install asset dependencies with bower
system(sprintf('%s install', $bower), $code);
if (0 !== $code) {
echo sprintf('Failed to install %s dependencies', $bower);
exit(1);
}
// Test if composer exists else install it
$composer = __DIR__ . '/composer.phar';
exec('composer', $output, $code);
if (0 !== $code && ! file_exists($composer)) {
system('curl -s http://getcomposer.org/installer | php');
system('chmod +x ' . $composer);
if (isset($argv[1]) && $argv[1] == '--no-dev') {
system($composer . ' install --optimize-autoloader --no-dev');
} else {
system($composer . ' install --dev --optimize-autoloader');
}
}
if (0 === $code) {
$composer = 'composer';
} elseif ( ! is_executable($composer)) {
system('chmod +x ' . $composer);
}
system($composer . ' self-update');
if (isset($argv[1]) && $argv[1] == '--no-dev') {
system($composer . ' install --optimize-autoloader --no-dev');
} else {
system($composer . ' install --dev --optimize-autoloader');
}
system('bin/setup assets:compile-less');
system('bin/setup assets:build-javascript');

View File

@@ -1,49 +0,0 @@
#!/usr/bin/env php
<?php
/*
* This file is part of the Symfony framework.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* Get all dependencies needed for Phraseanet (Windows Version)
*/
/* Set the variables gitDir and phpDir with a trailing slash if it is not set in Windows' %PATH%
* For example :
* $gitDir="c:/msysgit/bin/";
* $phpDir="c:/php5310/"
*/
$gitDir = "";
$phpDir = "";
chdir(__DIR__);
set_time_limit(0);
$composer = __DIR__ . '/composer.phar';
if ( ! file_exists($composer)) {
file_put_contents($composer, file_get_contents('http://getcomposer.org/installer'), LOCK_EX);
system($phpDir . 'php ' . $composer . ' install --dev');
}
system($phpDir . 'php ' . $composer . ' self-update');
system($phpDir . 'php ' . $composer . ' install --dev');
system($gitDir . 'git submodule init');
system($gitDir . 'git submodule update');
$iterator = new RecursiveDirectoryIterator(__DIR__ . '/lib/vendor/');
foreach ($iterator as $file) {
/* @var $file SplFileInfo */
if ($file->isDir()) {
$cmd = sprintf('cd %s && ' . $gitDir . 'git submodule init && ' . $gitDir . 'git submodule update', escapeshellarg($file->getPathname()));
system($cmd);
}
}