add icons for Character groups
This commit is contained in:
commit
2d9a41a5fe
3461 changed files with 594457 additions and 0 deletions
90
www/analytics/plugins/CoreConsole/Commands/CodeCoverage.php
Normal file
90
www/analytics/plugins/CoreConsole/Commands/CodeCoverage.php
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class CodeCoverage extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('tests:coverage');
|
||||
$this->setDescription('Run all phpunit tests and generate a combined code coverage');
|
||||
$this->addArgument('group', InputArgument::OPTIONAL, 'Run only a specific test group. Separate multiple groups by comma, for instance core,integration', '');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$phpCovPath = trim(shell_exec('which phpcov'));
|
||||
|
||||
if (empty($phpCovPath)) {
|
||||
|
||||
$output->writeln('phpcov not installed. please install pear.phpunit.de/phpcov.');
|
||||
return;
|
||||
}
|
||||
|
||||
$command = $this->getApplication()->find('tests:run');
|
||||
$arguments = array(
|
||||
'command' => 'tests:run',
|
||||
'--options' => sprintf('--coverage-php %s/tests/results/logs/%%group%%.cov', PIWIK_DOCUMENT_ROOT),
|
||||
);
|
||||
|
||||
$groups = $input->getArgument('group');
|
||||
if (!empty($groups)) {
|
||||
$arguments['group'] = $groups;
|
||||
} else {
|
||||
shell_exec(sprintf('rm %s/tests/results/logs/*.cov', PIWIK_DOCUMENT_ROOT));
|
||||
}
|
||||
|
||||
$inputObject = new ArrayInput($arguments);
|
||||
$inputObject->setInteractive($input->isInteractive());
|
||||
$command->run($inputObject, $output);
|
||||
|
||||
$command = 'phpcov';
|
||||
|
||||
// force xdebug usage for coverage options
|
||||
if (!extension_loaded('xdebug')) {
|
||||
|
||||
$output->writeln('<info>xdebug extension required for code coverage.</info>');
|
||||
|
||||
$output->writeln('<info>searching for xdebug extension...</info>');
|
||||
|
||||
$extensionDir = shell_exec('php-config --extension-dir');
|
||||
$xdebugFile = trim($extensionDir) . DIRECTORY_SEPARATOR . 'xdebug.so';
|
||||
|
||||
if (!file_exists($xdebugFile)) {
|
||||
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
$xdebugFile = $dialog->askAndValidate($output, 'xdebug not found. Please provide path to xdebug.so', function($xdebugFile) {
|
||||
return file_exists($xdebugFile);
|
||||
});
|
||||
} else {
|
||||
|
||||
$output->writeln('<info>xdebug extension found in extension path.</info>');
|
||||
}
|
||||
|
||||
$output->writeln("<info>using $xdebugFile as xdebug extension.</info>");
|
||||
|
||||
$command = sprintf('php -d zend_extension=%s %s', $xdebugFile, $phpCovPath);
|
||||
}
|
||||
|
||||
shell_exec(sprintf('rm -rf %s/tests/results/coverage/*', PIWIK_DOCUMENT_ROOT));
|
||||
|
||||
passthru(sprintf('cd %1$s && %2$s --merge --html tests/results/coverage/ --whitelist ./core/ --whitelist ./plugins/ --add-uncovered %1$s/tests/results/logs/', PIWIK_DOCUMENT_ROOT, $command));
|
||||
}
|
||||
|
||||
}
|
||||
55
www/analytics/plugins/CoreConsole/Commands/CoreArchiver.php
Normal file
55
www/analytics/plugins/CoreConsole/Commands/CoreArchiver.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\CronArchive;
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class CoreArchiver extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->configureArchiveCommand($this);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ($input->getOption('piwik-domain') && !$input->getOption('url')) {
|
||||
$_SERVER['argv'][] = '--url=' . $input->getOption('piwik-domain');
|
||||
}
|
||||
|
||||
include PIWIK_INCLUDE_PATH . '/misc/cron/archive.php';
|
||||
}
|
||||
|
||||
// This is reused by another console command
|
||||
static public function configureArchiveCommand(ConsoleCommand $command)
|
||||
{
|
||||
$command->setName('core:archive');
|
||||
$command->setDescription("Runs the CLI archiver. It is an important tool for general maintenance and to keep Piwik very fast.");
|
||||
$command->setHelp("* It is recommended to run the script with the option --piwik-domain=[piwik-server-url] only. Other options are not required.
|
||||
* This script should be executed every hour via crontab, or as a daemon.
|
||||
* You can also run it via http:// by specifying the Super User &token_auth=XYZ as a parameter ('Web Cron'),
|
||||
but it is recommended to run it via command line/CLI instead.
|
||||
* If you have any suggestion about this script, please let the team know at hello@piwik.org
|
||||
* Enjoy!");
|
||||
$command->addOption('url', null, InputOption::VALUE_REQUIRED, "Mandatory option as an alternative to '--piwik-domain'. Must be set to the Piwik base URL.\nFor example: --url=http://analytics.example.org/ or --url=https://example.org/piwik/");
|
||||
$command->addOption('force-all-websites', null, InputOption::VALUE_NONE, "If specified, the script will trigger archiving on all websites and all past dates.\nYou may use --force-all-periods=[seconds] to trigger archiving on those websites\nthat had visits in the last [seconds] seconds.");
|
||||
$command->addOption('force-all-periods', null, InputOption::VALUE_OPTIONAL, "Limits archiving to websites with some traffic in the last [seconds] seconds. \nFor example --force-all-periods=86400 will archive websites that had visits in the last 24 hours. \nIf [seconds] is not specified, all websites with visits in the last " . CronArchive::ARCHIVE_SITES_WITH_TRAFFIC_SINCE . "\n seconds (" . round(CronArchive::ARCHIVE_SITES_WITH_TRAFFIC_SINCE / 86400) . " days) will be archived.");
|
||||
$command->addOption('force-timeout-for-periods', null, InputOption::VALUE_OPTIONAL, "The current week/ current month/ current year will be processed at most every [seconds].\nIf not specified, defaults to " . CronArchive::SECONDS_DELAY_BETWEEN_PERIOD_ARCHIVES . ".");
|
||||
$command->addOption('force-date-last-n', null, InputOption::VALUE_REQUIRED, "This script calls the API with period=lastN. You can force the N in lastN by specifying this value.");
|
||||
$command->addOption('force-idsites', null, InputOption::VALUE_OPTIONAL, 'If specified, archiving will be processed only for these Sites Ids (comma separated)');
|
||||
$command->addOption('skip-idsites', null, InputOption::VALUE_OPTIONAL, 'If specified, archiving will be skipped for these websites (in case these website ids would have been archived).');
|
||||
$command->addOption('disable-scheduled-tasks', null, InputOption::VALUE_NONE, "Skips executing Scheduled tasks (sending scheduled reports, db optimization, etc.).");
|
||||
$command->addOption('xhprof', null, InputOption::VALUE_NONE, "Enables XHProf profiler for this archive.php run. Requires XHPRof (see tests/README.xhprof.md).");
|
||||
$command->addOption('accept-invalid-ssl-certificate', null, InputOption::VALUE_NONE, "It is _NOT_ recommended to use this argument. Instead, you should use a valid SSL certificate!\nIt can be useful if you specified --url=https://... or if you are using Piwik with force_ssl=1");
|
||||
}
|
||||
}
|
||||
58
www/analytics/plugins/CoreConsole/Commands/GenerateApi.php
Normal file
58
www/analytics/plugins/CoreConsole/Commands/GenerateApi.php
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class GenerateApi extends GeneratePluginBase
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('generate:api')
|
||||
->setDescription('Adds an API to an existing plugin')
|
||||
->addOption('pluginname', null, InputOption::VALUE_REQUIRED, 'The name of an existing plugin which does not have an API yet');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginName = $this->getPluginName($input, $output);
|
||||
|
||||
$exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExamplePlugin';
|
||||
$replace = array('ExamplePlugin' => $pluginName);
|
||||
$whitelistFiles = array('/API.php');
|
||||
|
||||
$this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
|
||||
|
||||
$this->writeSuccessMessage($output, array(
|
||||
sprintf('API.php for %s generated.', $pluginName),
|
||||
'You can now start adding API methods',
|
||||
'Enjoy!'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return array
|
||||
* @throws \RunTimeException
|
||||
*/
|
||||
protected function getPluginName(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginNames = $this->getPluginNamesHavingNotSpecificFile('API.php');
|
||||
$invalidName = 'You have to enter the name of an existing plugin which does not already have an API';
|
||||
|
||||
return $this->askPluginNameAndValidate($input, $output, $pluginNames, $invalidName);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Common;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class GenerateCommand extends GeneratePluginBase
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('generate:command')
|
||||
->setDescription('Adds a command to an existing plugin')
|
||||
->addOption('pluginname', null, InputOption::VALUE_REQUIRED, 'The name of an existing plugin')
|
||||
->addOption('command', null, InputOption::VALUE_REQUIRED, 'The name of the command you want to create');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginName = $this->getPluginName($input, $output);
|
||||
$commandName = $this->getCommandName($input, $output);
|
||||
|
||||
$exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExampleCommand';
|
||||
$replace = array(
|
||||
'ExampleCommand' => $pluginName,
|
||||
'examplecommand' => strtolower($pluginName),
|
||||
'HelloWorld' => $commandName,
|
||||
'helloworld' => strtolower($commandName)
|
||||
);
|
||||
|
||||
$whitelistFiles = array('/Commands', '/Commands/HelloWorld.php');
|
||||
|
||||
$this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
|
||||
|
||||
$this->writeSuccessMessage($output, array(
|
||||
sprintf('Command %s for plugin %s generated', $commandName, $pluginName)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return string
|
||||
* @throws \RunTimeException
|
||||
*/
|
||||
private function getCommandName(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$testname = $input->getOption('command');
|
||||
|
||||
$validate = function ($testname) {
|
||||
if (empty($testname)) {
|
||||
throw new \InvalidArgumentException('You have to enter a command name');
|
||||
}
|
||||
|
||||
return $testname;
|
||||
};
|
||||
|
||||
if (empty($testname)) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$testname = $dialog->askAndValidate($output, 'Enter the name of the command: ', $validate);
|
||||
} else {
|
||||
$validate($testname);
|
||||
}
|
||||
|
||||
$testname = ucfirst($testname);
|
||||
|
||||
return $testname;
|
||||
}
|
||||
|
||||
protected function getPluginName(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginNames = $this->getPluginNames();
|
||||
$invalidName = 'You have to enter the name of an existing plugin';
|
||||
|
||||
return $this->askPluginNameAndValidate($input, $output, $pluginNames, $invalidName);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class GenerateController extends GeneratePluginBase
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('generate:controller')
|
||||
->setDescription('Adds a Controller to an existing plugin')
|
||||
->addOption('pluginname', null, InputOption::VALUE_REQUIRED, 'The name of an existing plugin which does not have a Controller yet');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginName = $this->getPluginName($input, $output);
|
||||
|
||||
$exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExamplePlugin';
|
||||
$replace = array('ExamplePlugin' => $pluginName);
|
||||
$whitelistFiles = array('/Controller.php', '/templates', '/templates/index.twig');
|
||||
|
||||
$this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
|
||||
|
||||
$this->writeSuccessMessage($output, array(
|
||||
sprintf('Controller for %s generated.', $pluginName),
|
||||
'You can now start adding Controller actions',
|
||||
'Enjoy!'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return array
|
||||
* @throws \RunTimeException
|
||||
*/
|
||||
protected function getPluginName(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginNames = $this->getPluginNamesHavingNotSpecificFile('Controller.php');
|
||||
$invalidName = 'You have to enter the name of an existing plugin which does not already have a Controller';
|
||||
|
||||
return $this->askPluginNameAndValidate($input, $output, $pluginNames, $invalidName);
|
||||
}
|
||||
|
||||
}
|
||||
223
www/analytics/plugins/CoreConsole/Commands/GeneratePlugin.php
Normal file
223
www/analytics/plugins/CoreConsole/Commands/GeneratePlugin.php
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
|
||||
use Piwik\Filesystem;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class GeneratePlugin extends GeneratePluginBase
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('generate:plugin')
|
||||
->setAliases(array('generate:theme'))
|
||||
->setDescription('Generates a new plugin/theme including all needed files')
|
||||
->addOption('name', null, InputOption::VALUE_REQUIRED, 'Plugin name ([a-Z0-9_-])')
|
||||
->addOption('description', null, InputOption::VALUE_REQUIRED, 'Plugin description, max 150 characters')
|
||||
->addOption('pluginversion', null, InputOption::VALUE_OPTIONAL, 'Plugin version')
|
||||
->addOption('full', null, InputOption::VALUE_OPTIONAL, 'If a value is set, an API and a Controller will be created as well. Option is only available for creating plugins, not for creating themes.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$isTheme = $this->isTheme($input);
|
||||
$pluginName = $this->getPluginName($input, $output);
|
||||
$description = $this->getPluginDescription($input, $output);
|
||||
$version = $this->getPluginVersion($input, $output);
|
||||
$createFullPlugin = !$isTheme && $this->getCreateFullPlugin($input, $output);
|
||||
|
||||
$this->generatePluginFolder($pluginName);
|
||||
|
||||
if ($isTheme) {
|
||||
$exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExampleTheme';
|
||||
$replace = array(
|
||||
'ExampleTheme' => $pluginName,
|
||||
'ExampleDescription' => $description,
|
||||
'0.1.0' => $version
|
||||
);
|
||||
$whitelistFiles = array();
|
||||
|
||||
} else {
|
||||
|
||||
$exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExamplePlugin';
|
||||
$replace = array(
|
||||
'ExamplePlugin' => $pluginName,
|
||||
'ExampleDescription' => $description,
|
||||
'0.1.0' => $version
|
||||
);
|
||||
$whitelistFiles = array(
|
||||
'/ExamplePlugin.php',
|
||||
'/plugin.json',
|
||||
'/README.md',
|
||||
'/.travis.yml',
|
||||
'/screenshots',
|
||||
'/screenshots/.gitkeep',
|
||||
'/javascripts',
|
||||
'/javascripts/plugin.js',
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
$this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
|
||||
|
||||
$this->writeSuccessMessage($output, array(
|
||||
sprintf('%s %s %s generated.', $isTheme ? 'Theme' : 'Plugin', $pluginName, $version),
|
||||
'Enjoy!'
|
||||
));
|
||||
|
||||
if ($createFullPlugin) {
|
||||
$this->executePluginCommand($output, 'generate:api', $pluginName);
|
||||
$this->executePluginCommand($output, 'generate:controller', $pluginName);
|
||||
}
|
||||
}
|
||||
|
||||
private function executePluginCommand(OutputInterface $output, $commandName, $pluginName)
|
||||
{
|
||||
$command = $this->getApplication()->find($commandName);
|
||||
$arguments = array(
|
||||
'command' => $commandName,
|
||||
'--pluginname' => $pluginName
|
||||
);
|
||||
|
||||
$input = new ArrayInput($arguments);
|
||||
$command->run($input, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @return bool
|
||||
*/
|
||||
private function isTheme(InputInterface $input)
|
||||
{
|
||||
$commandName = $input->getFirstArgument();
|
||||
|
||||
return false !== strpos($commandName, 'theme');
|
||||
}
|
||||
|
||||
protected function generatePluginFolder($pluginName)
|
||||
{
|
||||
$pluginPath = $this->getPluginPath($pluginName);
|
||||
Filesystem::mkdir($pluginPath, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return array
|
||||
* @throws \RunTimeException
|
||||
*/
|
||||
protected function getPluginName(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$self = $this;
|
||||
|
||||
$validate = function ($pluginName) use ($self) {
|
||||
if (empty($pluginName)) {
|
||||
throw new \RunTimeException('You have to enter a plugin name');
|
||||
}
|
||||
|
||||
if (!Filesystem::isValidFilename($pluginName)) {
|
||||
throw new \RunTimeException(sprintf('The plugin name %s is not valid', $pluginName));
|
||||
}
|
||||
|
||||
$pluginPath = $self->getPluginPath($pluginName);
|
||||
|
||||
if (file_exists($pluginPath)) {
|
||||
throw new \RunTimeException('A plugin with this name already exists');
|
||||
}
|
||||
|
||||
return $pluginName;
|
||||
};
|
||||
|
||||
$pluginName = $input->getOption('name');
|
||||
|
||||
if (empty($pluginName)) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$pluginName = $dialog->askAndValidate($output, 'Enter a plugin name: ', $validate);
|
||||
} else {
|
||||
$validate($pluginName);
|
||||
}
|
||||
|
||||
$pluginName = ucfirst($pluginName);
|
||||
|
||||
return $pluginName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return mixed
|
||||
* @throws \RunTimeException
|
||||
*/
|
||||
protected function getPluginDescription(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$validate = function ($description) {
|
||||
if (empty($description)) {
|
||||
throw new \RunTimeException('You have to enter a description');
|
||||
}
|
||||
if (150 < strlen($description)) {
|
||||
throw new \RunTimeException('Description is too long, max 150 characters allowed.');
|
||||
}
|
||||
|
||||
return $description;
|
||||
};
|
||||
|
||||
$description = $input->getOption('description');
|
||||
|
||||
if (empty($description)) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$description = $dialog->askAndValidate($output, 'Enter a plugin description: ', $validate);
|
||||
} else {
|
||||
$validate($description);
|
||||
}
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return string
|
||||
*/
|
||||
protected function getPluginVersion(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$version = $input->getOption('pluginversion');
|
||||
|
||||
if (is_null($version)) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$version = $dialog->ask($output, 'Enter a plugin version number (default to 0.1.0): ', '0.1.0');
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getCreateFullPlugin(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$full = $input->getOption('full');
|
||||
|
||||
if (is_null($full)) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$full = $dialog->askConfirmation($output, 'Shall we also create an API and a Controller? (y/N)', false);
|
||||
}
|
||||
|
||||
return !empty($full);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
|
||||
use Piwik\Filesystem;
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
abstract class GeneratePluginBase extends ConsoleCommand
|
||||
{
|
||||
public function getPluginPath($pluginName)
|
||||
{
|
||||
return PIWIK_INCLUDE_PATH . '/plugins/' . ucfirst($pluginName);
|
||||
}
|
||||
|
||||
private function createFolderWithinPluginIfNotExists($pluginName, $folder)
|
||||
{
|
||||
$pluginPath = $this->getPluginPath($pluginName);
|
||||
|
||||
if (!file_exists($pluginName . $folder)) {
|
||||
Filesystem::mkdir($pluginPath . $folder, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected function createFileWithinPluginIfNotExists($pluginName, $fileName, $content)
|
||||
{
|
||||
$pluginPath = $this->getPluginPath($pluginName);
|
||||
|
||||
if (!file_exists($pluginPath . $fileName)) {
|
||||
file_put_contents($pluginPath . $fileName, $content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $templateFolder full path like /home/...
|
||||
* @param string $pluginName
|
||||
* @param array $replace array(key => value) $key will be replaced by $value in all templates
|
||||
* @param array $whitelistFiles If not empty, only given files/directories will be copied.
|
||||
* For instance array('/Controller.php', '/templates', '/templates/index.twig')
|
||||
*/
|
||||
protected function copyTemplateToPlugin($templateFolder, $pluginName, array $replace = array(), $whitelistFiles = array())
|
||||
{
|
||||
$replace['PLUGINNAME'] = $pluginName;
|
||||
|
||||
$files = array_merge(
|
||||
Filesystem::globr($templateFolder, '*'),
|
||||
// Also copy files starting with . such as .gitignore
|
||||
Filesystem::globr($templateFolder, '.*')
|
||||
);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$fileNamePlugin = str_replace($templateFolder, '', $file);
|
||||
|
||||
if (!empty($whitelistFiles) && !in_array($fileNamePlugin, $whitelistFiles)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_dir($file)) {
|
||||
$this->createFolderWithinPluginIfNotExists($pluginName, $fileNamePlugin);
|
||||
} else {
|
||||
$template = file_get_contents($file);
|
||||
foreach ($replace as $key => $value) {
|
||||
$template = str_replace($key, $value, $template);
|
||||
}
|
||||
|
||||
foreach ($replace as $key => $value) {
|
||||
$fileNamePlugin = str_replace($key, $value, $fileNamePlugin);
|
||||
}
|
||||
|
||||
$this->createFileWithinPluginIfNotExists($pluginName, $fileNamePlugin, $template);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected function getPluginNames()
|
||||
{
|
||||
$pluginDirs = \_glob(PIWIK_INCLUDE_PATH . '/plugins/*', GLOB_ONLYDIR);
|
||||
|
||||
$pluginNames = array();
|
||||
foreach ($pluginDirs as $pluginDir) {
|
||||
$pluginNames[] = basename($pluginDir);
|
||||
}
|
||||
|
||||
return $pluginNames;
|
||||
}
|
||||
|
||||
protected function getPluginNamesHavingNotSpecificFile($filename)
|
||||
{
|
||||
$pluginDirs = \_glob(PIWIK_INCLUDE_PATH . '/plugins/*', GLOB_ONLYDIR);
|
||||
|
||||
$pluginNames = array();
|
||||
foreach ($pluginDirs as $pluginDir) {
|
||||
if (!file_exists($pluginDir . '/' . $filename)) {
|
||||
$pluginNames[] = basename($pluginDir);
|
||||
}
|
||||
}
|
||||
|
||||
return $pluginNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return array
|
||||
* @throws \RunTimeException
|
||||
*/
|
||||
protected function askPluginNameAndValidate(InputInterface $input, OutputInterface $output, $pluginNames, $invalidArgumentException)
|
||||
{
|
||||
$validate = function ($pluginName) use ($pluginNames, $invalidArgumentException) {
|
||||
if (!in_array($pluginName, $pluginNames)) {
|
||||
throw new \InvalidArgumentException($invalidArgumentException);
|
||||
}
|
||||
|
||||
return $pluginName;
|
||||
};
|
||||
|
||||
$pluginName = $input->getOption('pluginname');
|
||||
|
||||
if (empty($pluginName)) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$pluginName = $dialog->askAndValidate($output, 'Enter the name of your plugin: ', $validate, false, null, $pluginNames);
|
||||
} else {
|
||||
$validate($pluginName);
|
||||
}
|
||||
|
||||
$pluginName = ucfirst($pluginName);
|
||||
|
||||
return $pluginName;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class GenerateSettings extends GeneratePluginBase
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('generate:settings')
|
||||
->setDescription('Adds a plugin setting class to an existing plugin')
|
||||
->addOption('pluginname', null, InputOption::VALUE_REQUIRED, 'The name of an existing plugin which does not have settings yet');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginName = $this->getPluginName($input, $output);
|
||||
|
||||
$exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExampleSettingsPlugin';
|
||||
$replace = array('ExampleSettingsPlugin' => $pluginName);
|
||||
$whitelistFiles = array('/Settings.php');
|
||||
|
||||
$this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
|
||||
|
||||
$this->writeSuccessMessage($output, array(
|
||||
sprintf('Settings.php for %s generated.', $pluginName),
|
||||
'You can now start defining your plugin settings',
|
||||
'Enjoy!'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return array
|
||||
* @throws \RunTimeException
|
||||
*/
|
||||
protected function getPluginName(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginNames = $this->getPluginNamesHavingNotSpecificFile('Settings.php');
|
||||
$invalidName = 'You have to enter the name of an existing plugin which does not already have settings';
|
||||
|
||||
return $this->askPluginNameAndValidate($input, $output, $pluginNames, $invalidName);
|
||||
}
|
||||
|
||||
}
|
||||
189
www/analytics/plugins/CoreConsole/Commands/GenerateTest.php
Normal file
189
www/analytics/plugins/CoreConsole/Commands/GenerateTest.php
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Common;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class GenerateTest extends GeneratePluginBase
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('generate:test')
|
||||
->setDescription('Adds a test to an existing plugin')
|
||||
->addOption('pluginname', null, InputOption::VALUE_REQUIRED, 'The name of an existing plugin')
|
||||
->addOption('testname', null, InputOption::VALUE_REQUIRED, 'The name of the test to create')
|
||||
->addOption('testtype', null, InputOption::VALUE_REQUIRED, 'Whether you want to create a "unit", "integration" or "database" test');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginName = $this->getPluginName($input, $output);
|
||||
$testName = $this->getTestName($input, $output);
|
||||
$testType = $this->getTestType($input, $output);
|
||||
|
||||
$exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExamplePlugin';
|
||||
$replace = array(
|
||||
'ExamplePlugin' => $pluginName,
|
||||
'SimpleTest' => $testName,
|
||||
'SimpleIntegrationTest' => $testName,
|
||||
'@group Plugins' => '@group ' . $testType
|
||||
);
|
||||
|
||||
$testClass = $this->getTestClass($testType);
|
||||
if(!empty($testClass)) {
|
||||
$replace['\PHPUnit_Framework_TestCase'] = $testClass;
|
||||
|
||||
}
|
||||
|
||||
$whitelistFiles = $this->getTestFilesWhitelist($testType);
|
||||
$this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles);
|
||||
|
||||
$this->writeSuccessMessage($output, array(
|
||||
sprintf('Test %s for plugin %s generated.', $testName, $pluginName),
|
||||
'You can now start writing beautiful tests!',
|
||||
|
||||
));
|
||||
|
||||
$this->writeSuccessMessage($output, array(
|
||||
'To run all your plugin tests, execute the command: ',
|
||||
sprintf('./console tests:run %s', $pluginName),
|
||||
'To run only this test: ',
|
||||
sprintf('./console tests:run %s', $testName),
|
||||
'Enjoy!'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return string
|
||||
* @throws \RunTimeException
|
||||
*/
|
||||
private function getTestName(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$testname = $input->getOption('testname');
|
||||
|
||||
$validate = function ($testname) {
|
||||
if (empty($testname)) {
|
||||
throw new \InvalidArgumentException('You have to enter a valid test name ');
|
||||
}
|
||||
|
||||
return $testname;
|
||||
};
|
||||
|
||||
if (empty($testname)) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$testname = $dialog->askAndValidate($output, 'Enter the name of the test: ', $validate);
|
||||
} else {
|
||||
$validate($testname);
|
||||
}
|
||||
|
||||
if (!Common::stringEndsWith(strtolower($testname), 'test')) {
|
||||
$testname = $testname . 'Test';
|
||||
}
|
||||
|
||||
$testname = ucfirst($testname);
|
||||
|
||||
return $testname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return array
|
||||
* @throws \RunTimeException
|
||||
*/
|
||||
protected function getPluginName(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginNames = $this->getPluginNames();
|
||||
$invalidName = 'You have to enter the name of an existing plugin';
|
||||
|
||||
return $this->askPluginNameAndValidate($input, $output, $pluginNames, $invalidName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @return string
|
||||
*/
|
||||
private function getTestClass($testType)
|
||||
{
|
||||
if ('Database' == $testType) {
|
||||
return '\DatabaseTestCase';
|
||||
}
|
||||
if ('Unit' == $testType) {
|
||||
return '\PHPUnit_Framework_TestCase';
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getValidTypes()
|
||||
{
|
||||
return array('unit', 'integration', 'database');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return string Unit, Integration, Database
|
||||
*/
|
||||
private function getTestType(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$testtype = $input->getOption('testtype');
|
||||
|
||||
$self = $this;
|
||||
|
||||
$validate = function ($testtype) use ($self) {
|
||||
if (empty($testtype) || !in_array($testtype, $self->getValidTypes())) {
|
||||
throw new \InvalidArgumentException('You have to enter a valid test type: ' . implode(" or ", $self->getValidTypes()));
|
||||
}
|
||||
return $testtype;
|
||||
};
|
||||
|
||||
if (empty($testtype)) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$testtype = $dialog->askAndValidate($output, 'Enter the type of the test to generate ('. implode(", ", $this->getValidTypes()).'): ', $validate, false, null, $this->getValidTypes());
|
||||
} else {
|
||||
$validate($testtype);
|
||||
}
|
||||
|
||||
$testtype = ucfirst($testtype);
|
||||
return $testtype;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getTestFilesWhitelist($testType)
|
||||
{
|
||||
if('Integration' == $testType) {
|
||||
return array(
|
||||
'/.gitignore',
|
||||
'/tests',
|
||||
'/tests/SimpleIntegrationTest.php',
|
||||
'/tests/expected',
|
||||
'/tests/expected/test___API.get_day.xml',
|
||||
'/tests/expected/test___Goals.getItemsSku_day.xml',
|
||||
'/tests/processed',
|
||||
'/tests/processed/.gitignore',
|
||||
'/tests/fixtures',
|
||||
'/tests/fixtures/SimpleFixtureTrackFewVisits.php'
|
||||
);
|
||||
}
|
||||
return array(
|
||||
'/tests',
|
||||
'/tests/SimpleTest.php'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class GenerateVisualizationPlugin extends GeneratePlugin
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('generate:visualizationplugin')
|
||||
->setDescription('Generates a new visualization plugin including all needed files')
|
||||
->addOption('name', null, InputOption::VALUE_REQUIRED, 'Plugin name ([a-Z0-9_-])')
|
||||
->addOption('visualizationname', null, InputOption::VALUE_REQUIRED, 'Visualization name ([a-Z0-9])')
|
||||
->addOption('description', null, InputOption::VALUE_REQUIRED, 'Plugin description, max 150 characters')
|
||||
->addOption('pluginversion', null, InputOption::VALUE_OPTIONAL, 'Plugin version')
|
||||
->addOption('full', null, InputOption::VALUE_OPTIONAL, 'If a value is set, an API and a Controller will be created as well. Option is only available for creating plugins, not for creating themes.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$pluginName = $this->getPluginName($input, $output);
|
||||
$description = $this->getPluginDescription($input, $output);
|
||||
$version = $this->getPluginVersion($input, $output);
|
||||
$visualizationName = $this->getVisualizationName($input, $output);
|
||||
|
||||
$this->generatePluginFolder($pluginName);
|
||||
|
||||
$exampleFolder = PIWIK_INCLUDE_PATH . '/plugins/ExampleVisualization';
|
||||
$replace = array(
|
||||
'SimpleTable' => $visualizationName,
|
||||
'simpleTable' => lcfirst($visualizationName),
|
||||
'Simple Table' => $visualizationName,
|
||||
'ExampleVisualization' => $pluginName,
|
||||
'ExampleVisualizationDescription' => $description
|
||||
);
|
||||
|
||||
$this->copyTemplateToPlugin($exampleFolder, $pluginName, $replace, $whitelistFiles = array());
|
||||
|
||||
$this->writeSuccessMessage($output, array(
|
||||
sprintf('Visualization plugin %s %s generated.', $pluginName, $version),
|
||||
'Enjoy!'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
* @return string
|
||||
* @throws \RunTimeException
|
||||
*/
|
||||
private function getVisualizationName(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$self = $this;
|
||||
|
||||
$validate = function ($visualizationName) use ($self) {
|
||||
if (empty($visualizationName)) {
|
||||
throw new \RunTimeException('You have to enter a visualization name');
|
||||
}
|
||||
|
||||
if (!ctype_alnum($visualizationName)) {
|
||||
throw new \RunTimeException(sprintf('The visualization name %s is not valid', $visualizationName));
|
||||
}
|
||||
|
||||
return $visualizationName;
|
||||
};
|
||||
|
||||
$visualizationName = $input->getOption('visualizationname');
|
||||
|
||||
if (empty($visualizationName)) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$visualizationName = $dialog->askAndValidate($output, 'Enter a visualization name: ', $validate);
|
||||
} else {
|
||||
$validate($visualizationName);
|
||||
}
|
||||
|
||||
$visualizationName = ucfirst($visualizationName);
|
||||
|
||||
return $visualizationName;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
142
www/analytics/plugins/CoreConsole/Commands/GitCommit.php
Normal file
142
www/analytics/plugins/CoreConsole/Commands/GitCommit.php
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class GitCommit extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('git:commit')
|
||||
->setDescription('Commit')
|
||||
->addOption('message', 'm', InputOption::VALUE_REQUIRED, 'Commit Message');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$submodules = $this->getSubmodulePaths();
|
||||
|
||||
foreach ($submodules as $submodule) {
|
||||
if (empty($submodule)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$status = $this->getStatusOfSubmodule($submodule);
|
||||
if (false !== strpos($status, '?? ')) {
|
||||
$output->writeln(sprintf('<error>%s has untracked files or folders. Delete or add them and try again.</error>', $submodule));
|
||||
$output->writeln('<error>Status:</error>');
|
||||
$output->writeln(sprintf('<comment>%s</comment>', $status));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$commitMessage = $input->getOption('message');
|
||||
|
||||
if (empty($commitMessage)) {
|
||||
$output->writeln('No message specified. Use option -m or --message.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$this->hasChangesToBeCommitted()) {
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
$question = '<question>There are no changes to be commited in the super repo, do you just want to commit and converge submodules?</question>';
|
||||
if (!$dialog->askConfirmation($output, $question, false)) {
|
||||
$output->writeln('<info>Cool, nothing done. Stage files using "git add" and try again.</info>');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($submodules as $submodule) {
|
||||
if (empty($submodule)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$status = $this->getStatusOfSubmodule($submodule);
|
||||
if (empty($status)) {
|
||||
$output->writeln(sprintf('%s has no changes, will ignore', $submodule));
|
||||
continue;
|
||||
}
|
||||
|
||||
$cmd = sprintf('cd %s/%s && git pull && git add . && git commit -am "%s"', PIWIK_DOCUMENT_ROOT, $submodule, $commitMessage);
|
||||
$this->passthru($cmd, $output);
|
||||
}
|
||||
|
||||
if ($this->hasChangesToBeCommitted()) {
|
||||
$cmd = sprintf('cd %s && git commit -m "%s"', PIWIK_DOCUMENT_ROOT, $commitMessage);
|
||||
$this->passthru($cmd, $output);
|
||||
}
|
||||
|
||||
foreach ($submodules as $submodule) {
|
||||
if (empty($submodule)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cmd = sprintf('cd %s && git add %s', PIWIK_DOCUMENT_ROOT, $submodule);
|
||||
$this->passthru($cmd, $output);
|
||||
}
|
||||
|
||||
if ($this->hasChangesToBeCommitted()) {
|
||||
$cmd = sprintf('cd %s && git commit -m "Updating submodules"', PIWIK_DOCUMENT_ROOT);
|
||||
$this->passthru($cmd, $output);
|
||||
}
|
||||
}
|
||||
|
||||
private function passthru($cmd, OutputInterface $output)
|
||||
{
|
||||
$output->writeln('Executing command: ' . $cmd);
|
||||
passthru($cmd);
|
||||
}
|
||||
|
||||
private function hasChangesToBeCommitted()
|
||||
{
|
||||
$cmd = sprintf('cd %s && git status --porcelain', PIWIK_DOCUMENT_ROOT);
|
||||
$result = shell_exec($cmd);
|
||||
$result = trim($result);
|
||||
|
||||
if (false !== strpos($result, 'M ')) {
|
||||
// stages
|
||||
return true;
|
||||
}
|
||||
|
||||
if (false !== strpos($result, 'MM ')) {
|
||||
// staged and modified
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function getSubmodulePaths()
|
||||
{
|
||||
$cmd = sprintf("grep path .gitmodules | sed 's/.*= //'");
|
||||
$submodules = shell_exec($cmd);
|
||||
$submodules = explode("\n", $submodules);
|
||||
|
||||
return $submodules;
|
||||
}
|
||||
|
||||
protected function getStatusOfSubmodule($submodule)
|
||||
{
|
||||
$cmd = sprintf('cd %s/%s && git status --porcelain', PIWIK_DOCUMENT_ROOT, $submodule);
|
||||
$status = trim(shell_exec($cmd));
|
||||
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
55
www/analytics/plugins/CoreConsole/Commands/GitPull.php
Normal file
55
www/analytics/plugins/CoreConsole/Commands/GitPull.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class GitPull extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('git:pull');
|
||||
$this->setDescription('Pull Piwik repo and all submodules');
|
||||
}
|
||||
|
||||
protected function getBranchName()
|
||||
{
|
||||
$cmd = sprintf('cd %s && git rev-parse --abbrev-ref HEAD', PIWIK_DOCUMENT_ROOT);
|
||||
$branch = shell_exec($cmd);
|
||||
|
||||
return trim($branch);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
if ('master' != $this->getBranchName()) {
|
||||
$output->writeln('<info>Doing nothing because you are not on the master branch in super repo.</info>');
|
||||
return;
|
||||
}
|
||||
|
||||
$cmd = sprintf('cd %s && git checkout master && git pull && git submodule update --init --recursive --remote', PIWIK_DOCUMENT_ROOT);
|
||||
$this->passthru($cmd, $output);
|
||||
|
||||
$cmd = 'git submodule foreach "(git checkout master; git pull)&"';
|
||||
$this->passthru($cmd, $output);
|
||||
}
|
||||
|
||||
private function passthru($cmd, OutputInterface $output)
|
||||
{
|
||||
$output->writeln('Executing command: ' . $cmd);
|
||||
passthru($cmd);
|
||||
}
|
||||
}
|
||||
43
www/analytics/plugins/CoreConsole/Commands/GitPush.php
Normal file
43
www/analytics/plugins/CoreConsole/Commands/GitPush.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class GitPush extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('git:push');
|
||||
$this->setDescription('Push Piwik repo and all submodules');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$cmd = sprintf('cd %s && git push --recurse-submodules=on-demand', PIWIK_DOCUMENT_ROOT);
|
||||
$output->writeln('Executing command: ' . $cmd);
|
||||
passthru($cmd);
|
||||
}
|
||||
|
||||
private function hasUnpushedCommits()
|
||||
{
|
||||
$cmd = sprintf('cd %s && git log @{u}..',PIWIK_DOCUMENT_ROOT);
|
||||
$hasUnpushedCommits = shell_exec($cmd);
|
||||
$hasUnpushedCommits = trim($hasUnpushedCommits);
|
||||
|
||||
return !empty($hasUnpushedCommits);
|
||||
}
|
||||
}
|
||||
68
www/analytics/plugins/CoreConsole/Commands/ManagePlugin.php
Normal file
68
www/analytics/plugins/CoreConsole/Commands/ManagePlugin.php
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Plugin\Manager;
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* core:plugin console command.
|
||||
*/
|
||||
class ManagePlugin extends ConsoleCommand
|
||||
{
|
||||
private $operations = array();
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('core:plugin');
|
||||
$this->setDescription("Perform various actions regarding one or more plugins.");
|
||||
$this->addArgument("operation", InputArgument::REQUIRED, "Operation to apply (can be 'activate' or 'deactivate').");
|
||||
$this->addArgument("plugins", InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'Plugin name(s) to activate.');
|
||||
$this->addOption('domain', null, InputOption::VALUE_REQUIRED, "The domain to activate the plugin for.");
|
||||
|
||||
$this->operations['activate'] = 'activatePlugin';
|
||||
$this->operations['deactivate'] = 'deactivatePlugin';
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute command like: ./console cloudadmin:plugin activate CustomAlerts --piwik-domain=testcustomer.piwik.pro
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$operation = $input->getArgument("operation");
|
||||
$plugins = $input->getArgument('plugins');
|
||||
|
||||
if (empty($this->operations[$operation])) {
|
||||
throw new Exception("Invalid operation '$operation'.");
|
||||
}
|
||||
|
||||
$fn = $this->operations[$operation];
|
||||
foreach ($plugins as $plugin) {
|
||||
call_user_func(array($this, $fn), $input, $output, $plugin);
|
||||
}
|
||||
}
|
||||
|
||||
private function activatePlugin(InputInterface $input, OutputInterface $output, $plugin)
|
||||
{
|
||||
Manager::getInstance()->activatePlugin($plugin, $input, $output);
|
||||
|
||||
$output->writeln("Activated plugin <info>$plugin</info>");
|
||||
}
|
||||
|
||||
private function deactivatePlugin(InputInterface $input, OutputInterface $output, $plugin)
|
||||
{
|
||||
Manager::getInstance()->deactivatePlugin($plugin, $input, $output);
|
||||
|
||||
$output->writeln("Deactivated plugin <info>$plugin</info>");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class ManageTestFiles extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('development:test-files');
|
||||
$this->setDescription("Manage test files.");
|
||||
|
||||
$this->addArgument('operation', InputArgument::REQUIRED, 'The operation to apply. Supported operations include: '
|
||||
. '"copy"');
|
||||
$this->addOption('file', null, InputOption::VALUE_REQUIRED, "The file (or files) to apply the operation to.");
|
||||
|
||||
// TODO: allow copying by regex pattern
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$operation = $input->getArgument('operation');
|
||||
|
||||
if ($operation == 'copy') {
|
||||
$this->copy($input, $output);
|
||||
} else {
|
||||
throw new \Exception("Invalid operation '$operation'.");
|
||||
}
|
||||
}
|
||||
|
||||
private function copy($input, $output)
|
||||
{
|
||||
$file = $input->getOption('file');
|
||||
|
||||
$prefix = PIWIK_INCLUDE_PATH . '/tests/PHPUnit/Integration/processed/';
|
||||
$guesses = array(
|
||||
'/' . $file,
|
||||
$prefix . $file,
|
||||
$prefix . $file . '.xml'
|
||||
);
|
||||
|
||||
foreach ($guesses as $guess) {
|
||||
if (is_file($guess)) {
|
||||
$file = $guess;
|
||||
}
|
||||
}
|
||||
|
||||
copy($file, PIWIK_INCLUDE_PATH . '/tests/PHPUnit/Integration/expected/' . basename($file));
|
||||
}
|
||||
}
|
||||
87
www/analytics/plugins/CoreConsole/Commands/RunTests.php
Normal file
87
www/analytics/plugins/CoreConsole/Commands/RunTests.php
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class RunTests extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('tests:run');
|
||||
$this->setDescription('Run Piwik PHPUnit tests one group after the other');
|
||||
$this->addArgument('group', InputArgument::OPTIONAL, 'Run only a specific test group. Separate multiple groups by comma, for instance core,integration', '');
|
||||
$this->addOption('options', 'o', InputOption::VALUE_OPTIONAL, 'All options will be forwarded to phpunit', '');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$options = $input->getOption('options');
|
||||
$groups = $input->getArgument('group');
|
||||
|
||||
$groups = explode(",", $groups);
|
||||
$groups = array_map('ucfirst', $groups);
|
||||
$groups = array_filter($groups, 'strlen');
|
||||
|
||||
$command = 'phpunit';
|
||||
|
||||
// force xdebug usage for coverage options
|
||||
if (false !== strpos($options, '--coverage') && !extension_loaded('xdebug')) {
|
||||
|
||||
$output->writeln('<info>xdebug extension required for code coverage.</info>');
|
||||
|
||||
$output->writeln('<info>searching for xdebug extension...</info>');
|
||||
|
||||
$extensionDir = shell_exec('php-config --extension-dir');
|
||||
$xdebugFile = trim($extensionDir) . DIRECTORY_SEPARATOR . 'xdebug.so';
|
||||
|
||||
if (!file_exists($xdebugFile)) {
|
||||
|
||||
$dialog = $this->getHelperSet()->get('dialog');
|
||||
|
||||
$xdebugFile = $dialog->askAndValidate($output, 'xdebug not found. Please provide path to xdebug.so', function($xdebugFile) {
|
||||
return file_exists($xdebugFile);
|
||||
});
|
||||
} else {
|
||||
|
||||
$output->writeln('<info>xdebug extension found in extension path.</info>');
|
||||
}
|
||||
|
||||
$output->writeln("<info>using $xdebugFile as xdebug extension.</info>");
|
||||
|
||||
$phpunitPath = trim(shell_exec('which phpunit'));
|
||||
|
||||
$command = sprintf('php -d zend_extension=%s %s', $xdebugFile, $phpunitPath);
|
||||
}
|
||||
|
||||
if(empty($groups)) {
|
||||
$groups = $this->getTestsGroups();
|
||||
}
|
||||
foreach($groups as $group) {
|
||||
$params = '--group ' . $group . ' ' . str_replace('%group%', $group, $options);
|
||||
$cmd = sprintf('cd %s/tests/PHPUnit && %s %s', PIWIK_DOCUMENT_ROOT, $command, $params);
|
||||
$output->writeln('Executing command: <info>' . $cmd . '</info>');
|
||||
passthru($cmd);
|
||||
$output->writeln("");
|
||||
}
|
||||
}
|
||||
|
||||
private function getTestsGroups()
|
||||
{
|
||||
return array('Core', 'Plugins', 'Integration', 'UI');
|
||||
}
|
||||
|
||||
}
|
||||
70
www/analytics/plugins/CoreConsole/Commands/RunUITests.php
Normal file
70
www/analytics/plugins/CoreConsole/Commands/RunUITests.php
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
class RunUITests extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('tests:run-ui');
|
||||
$this->setDescription('Run screenshot tests');
|
||||
$this->addArgument('specs', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Run only a specific test spec. Separate multiple specs by comma, for instance core,integration', array());
|
||||
$this->addOption("persist-fixture-data", null, InputOption::VALUE_NONE, "Persist test data in a database and do not execute tear down.");
|
||||
$this->addOption('keep-symlinks', null, InputOption::VALUE_NONE, "Keep recursive directory symlinks so test pages can be viewed in a browser.");
|
||||
$this->addOption('print-logs', null, InputOption::VALUE_NONE, "Print webpage logs even if tests succeed.");
|
||||
$this->addOption('drop', null, InputOption::VALUE_NONE, "Drop the existing database and re-setup a persisted fixture.");
|
||||
$this->addOption('plugin', null, InputOption::VALUE_REQUIRED, "Execute all tests for a plugin.");
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$specs = $input->getArgument('specs');
|
||||
$persistFixtureData = $input->getOption("persist-fixture-data");
|
||||
$keepSymlinks = $input->getOption('keep-symlinks');
|
||||
$printLogs = $input->getOption('print-logs');
|
||||
$drop = $input->getOption('drop');
|
||||
$plugin = $input->getOption('plugin');
|
||||
|
||||
$options = array();
|
||||
if ($persistFixtureData) {
|
||||
$options[] = "--persist-fixture-data";
|
||||
}
|
||||
|
||||
if ($keepSymlinks) {
|
||||
$options[] = "--keep-symlinks";
|
||||
}
|
||||
|
||||
if ($printLogs) {
|
||||
$options[] = "--print-logs";
|
||||
}
|
||||
|
||||
if ($drop) {
|
||||
$options[] = "--drop";
|
||||
}
|
||||
|
||||
if ($plugin) {
|
||||
$options[] = "--plugin=" . $plugin;
|
||||
}
|
||||
$options = implode(" ", $options);
|
||||
|
||||
$specs = implode(" ", $specs);
|
||||
|
||||
$cmd = "phantomjs '" . PIWIK_INCLUDE_PATH . "/tests/lib/screenshot-testing/run-tests.js' $options $specs";
|
||||
|
||||
$output->writeln('Executing command: <info>' . $cmd . '</info>');
|
||||
$output->writeln('');
|
||||
|
||||
passthru($cmd);
|
||||
}
|
||||
}
|
||||
156
www/analytics/plugins/CoreConsole/Commands/SetupFixture.php
Normal file
156
www/analytics/plugins/CoreConsole/Commands/SetupFixture.php
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Url;
|
||||
use Piwik\Piwik;
|
||||
use Piwik\Config;
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Console commands that sets up a fixture either in a local MySQL database or a remote one.
|
||||
*
|
||||
* TODO: use this console command in UI tests instead of setUpDatabase.php/tearDownDatabase.php scripts
|
||||
*/
|
||||
class SetupFixture extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('tests:setup-fixture');
|
||||
$this->setDescription('Create a database and fill it with data using a Piwik test fixture.');
|
||||
|
||||
$this->addArgument('fixture', InputArgument::REQUIRED,
|
||||
"The class name of the fixture to apply. Doesn't need to have a namespace if it exists in the " .
|
||||
"Piwik\\Tests\\Fixtures namespace.");
|
||||
|
||||
$this->addOption('db-name', null, InputOption::VALUE_REQUIRED,
|
||||
"The name of the database that will contain the fixture data. This option is required to be set.");
|
||||
$this->addOption('file', null, InputOption::VALUE_REQUIRED,
|
||||
"The file location of the fixture. If this option is included the file will be required explicitly.");
|
||||
$this->addOption('db-host', null, InputOption::VALUE_REQUIRED,
|
||||
"The hostname of the MySQL database to use. Uses the default config value if not specified.");
|
||||
$this->addOption('db-user', null, InputOption::VALUE_REQUIRED,
|
||||
"The name of the MySQL user to use. Uses the default config value if not specified.");
|
||||
$this->addOption('db-pass', null, InputOption::VALUE_REQUIRED,
|
||||
"The MySQL user password to use. Uses the default config value if not specified.");
|
||||
$this->addOption('teardown', null, InputOption::VALUE_NONE,
|
||||
"If specified, the fixture will be torn down and the database deleted. Won't work if the --db-name " .
|
||||
"option isn't supplied.");
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$dbName = $input->getOption('db-name');
|
||||
if (!$dbName) {
|
||||
throw new \Exception("Required argument --db-name is not set.");
|
||||
}
|
||||
|
||||
$this->requireFixtureFiles();
|
||||
$this->setIncludePathAsInTestBootstrap();
|
||||
|
||||
$file = $input->getOption('file');
|
||||
if ($file) {
|
||||
if (is_file($file)) {
|
||||
require_once $file;
|
||||
} else if (is_file(PIWIK_INCLUDE_PATH . '/' . $file)) {
|
||||
require_once PIWIK_INCLUDE_PATH . '/' . $file;
|
||||
} else {
|
||||
throw new \Exception("Cannot find --file option file '$file'.");
|
||||
}
|
||||
}
|
||||
|
||||
$host = Url::getHost();
|
||||
if (empty($host)) {
|
||||
Url::setHost('localhost');
|
||||
}
|
||||
|
||||
// get the fixture class
|
||||
$fixtureClass = $input->getArgument('fixture');
|
||||
if (class_exists("Piwik\\Tests\\Fixtures\\" . $fixtureClass)) {
|
||||
$fixtureClass = "Piwik\\Tests\\Fixtures\\" . $fixtureClass;
|
||||
}
|
||||
|
||||
if (!class_exists($fixtureClass)) {
|
||||
throw new \Exception("Cannot find fixture class '$fixtureClass'.");
|
||||
}
|
||||
|
||||
// create the fixture
|
||||
$fixture = new $fixtureClass();
|
||||
$fixture->dbName = $dbName;
|
||||
$fixture->printToScreen = true;
|
||||
|
||||
Config::getInstance()->setTestEnvironment();
|
||||
$fixture->createConfig = false;
|
||||
|
||||
// setup database overrides
|
||||
$testingEnvironment = $fixture->getTestEnvironment();
|
||||
|
||||
$optionsToOverride = array(
|
||||
'dbname' => $dbName,
|
||||
'host' => $input->getOption('db-host'),
|
||||
'user' => $input->getOption('db-user'),
|
||||
'password' => $input->getOption('db-pass')
|
||||
);
|
||||
foreach ($optionsToOverride as $configOption => $value) {
|
||||
if ($value) {
|
||||
$configOverride = $testingEnvironment->configOverride;
|
||||
$configOverride['database_tests'][$configOption] = $configOverride['database'][$configOption] = $value;
|
||||
$testingEnvironment->configOverride = $configOverride;
|
||||
|
||||
Config::getInstance()->database[$configOption] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// perform setup and/or teardown
|
||||
if ($input->getOption('teardown')) {
|
||||
$testingEnvironment->save();
|
||||
$fixture->performTearDown();
|
||||
} else {
|
||||
$fixture->performSetUp();
|
||||
}
|
||||
|
||||
$this->writeSuccessMessage($output, array("Fixture successfully setup!"));
|
||||
}
|
||||
|
||||
private function requireFixtureFiles()
|
||||
{
|
||||
require_once "PHPUnit/Autoload.php";
|
||||
|
||||
require_once PIWIK_INCLUDE_PATH . '/libs/PiwikTracker/PiwikTracker.php';
|
||||
require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/FakeAccess.php';
|
||||
require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/TestingEnvironment.php';
|
||||
require_once PIWIK_INCLUDE_PATH . '/tests/PHPUnit/Fixture.php';
|
||||
|
||||
$fixturesToLoad = array(
|
||||
'/tests/PHPUnit/Fixtures/*.php',
|
||||
'/tests/PHPUnit/UI/Fixtures/*.php',
|
||||
);
|
||||
foreach($fixturesToLoad as $fixturePath) {
|
||||
foreach (glob(PIWIK_INCLUDE_PATH . $fixturePath) as $file) {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function setIncludePathAsInTestBootstrap()
|
||||
{
|
||||
if (!defined('PIWIK_INCLUDE_SEARCH_PATH')) {
|
||||
define('PIWIK_INCLUDE_SEARCH_PATH', get_include_path()
|
||||
. PATH_SEPARATOR . PIWIK_INCLUDE_PATH . '/core'
|
||||
. PATH_SEPARATOR . PIWIK_INCLUDE_PATH . '/libs'
|
||||
. PATH_SEPARATOR . PIWIK_INCLUDE_PATH . '/plugins');
|
||||
}
|
||||
@ini_set('include_path', PIWIK_INCLUDE_SEARCH_PATH);
|
||||
@set_include_path(PIWIK_INCLUDE_SEARCH_PATH);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Http;
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class SyncUITestScreenshots extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('development:sync-ui-test-screenshots');
|
||||
$this->setDescription('For Piwik core devs. Copies screenshots '
|
||||
. 'from travis artifacts to tests/PHPUnit/UI/expected-ui-screenshots/');
|
||||
$this->addArgument('buildnumber', InputArgument::REQUIRED, 'Travis build number you want to sync.');
|
||||
$this->addArgument('screenshotsRegex', InputArgument::OPTIONAL,
|
||||
'A regex to use when selecting screenshots to copy. If not supplied all screenshots are copied.', '.*');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$buildNumber = $input->getArgument('buildnumber');
|
||||
$screenshotsRegex = $input->getArgument('screenshotsRegex');
|
||||
|
||||
if (empty($buildNumber)) {
|
||||
throw new \InvalidArgumentException('Missing build number.');
|
||||
}
|
||||
|
||||
$urlBase = sprintf('http://builds-artifacts.piwik.org/ui-tests.master/%s', $buildNumber);
|
||||
$diffviewer = Http::sendHttpRequest($urlBase . "/screenshot-diffs/diffviewer.html", $timeout = 60);
|
||||
|
||||
$dom = new \DOMDocument();
|
||||
$dom->loadHTML($diffviewer);
|
||||
foreach ($dom->getElementsByTagName("tr") as $row) {
|
||||
$columns = $row->getElementsByTagName("td");
|
||||
|
||||
$nameColumn = $columns->item(0);
|
||||
$processedColumn = $columns->item(2);
|
||||
|
||||
$testPlugin = null;
|
||||
if ($nameColumn
|
||||
&& preg_match("/\(for ([a-zA-Z_]+) plugin\)/", $dom->saveXml($nameColumn), $matches)
|
||||
) {
|
||||
$testPlugin = $matches[1];
|
||||
}
|
||||
|
||||
$file = null;
|
||||
if ($processedColumn
|
||||
&& preg_match("/href=\".*\/(.*)\"/", $dom->saveXml($processedColumn), $matches)
|
||||
) {
|
||||
$file = $matches[1];
|
||||
}
|
||||
|
||||
if ($file !== null
|
||||
&& preg_match("/" . $screenshotsRegex . "/", $file)
|
||||
) {
|
||||
if ($testPlugin == null) {
|
||||
$downloadTo = "tests/PHPUnit/UI/expected-ui-screenshots/$file";
|
||||
} else {
|
||||
$downloadTo = "plugins/$testPlugin/tests/UI/expected-ui-screenshots/$file";
|
||||
}
|
||||
|
||||
$output->write("<info>Downloading $file to .$downloadTo...</info>\n");
|
||||
Http::sendHttpRequest("$urlBase/processed-ui-screenshots/$file", $timeout = 60, $userAgent = null,
|
||||
PIWIK_DOCUMENT_ROOT . "/" . $downloadTo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
www/analytics/plugins/CoreConsole/Commands/WatchLog.php
Normal file
33
www/analytics/plugins/CoreConsole/Commands/WatchLog.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/**
|
||||
* Piwik - Open source web analytics
|
||||
*
|
||||
* @link http://piwik.org
|
||||
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Piwik\Plugins\CoreConsole\Commands;
|
||||
|
||||
use Piwik\Plugin\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
*/
|
||||
class WatchLog extends ConsoleCommand
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('log:watch');
|
||||
$this->setDescription('Outputs the last parts of the log files and follows as the log file grows. Does not work on Windows');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$cmd = sprintf('tail -f %s/tmp/logs/*.log', PIWIK_DOCUMENT_ROOT);
|
||||
|
||||
$output->writeln('Executing command: ' . $cmd);
|
||||
passthru($cmd);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue