Skip to content
This repository has been archived by the owner on Apr 18, 2023. It is now read-only.

Commit

Permalink
Merge pull request #12 from baleen/migrate-updates-storage
Browse files Browse the repository at this point in the history
Migrate Updates Storage
  • Loading branch information
gsomoza committed Aug 13, 2015
2 parents 09fcbc2 + 4df29f5 commit 4d75275
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 20 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"require": {
"symfony/console": "^2.7",
"psr/log": "^1.0",
"baleen/migrations": "^0.5",
"baleen/migrations": "^0.6",
"symfony/yaml": "^2.7",
"symfony/config": "^2.7",
"league/container": "^1.3",
Expand Down
29 changes: 28 additions & 1 deletion src/Command/Timeline/AbstractTimelineCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
namespace Baleen\Cli\Command\Timeline;

use Baleen\Cli\Command\AbstractCommand;
use Baleen\Migrations\Storage\StorageInterface;
use Baleen\Migrations\Timeline;
use Symfony\Component\Console\Input\InputOption;

Expand All @@ -33,17 +34,27 @@ abstract class AbstractTimelineCommand extends AbstractCommand
{
const COMMAND_GROUP = 'timeline';
const OPT_DRY_RUN = 'dry-run';
const OPT_NO_STORAGE = 'no-storage';

/** @var Timeline */
protected $timeline;

/** @var StorageInterface */
protected $storage;

/**
* @inheritDoc
*/
public function configure()
{
parent::configure();
$this->addOption(self::OPT_DRY_RUN, 'd', InputOption::VALUE_NONE, 'Execute the migration on dry-run mode.');
$this->addOption(self::OPT_DRY_RUN, 'd', InputOption::VALUE_NONE, 'Execute the migration on dry-run mode.')
->addOption(
self::OPT_NO_STORAGE,
null,
InputOption::VALUE_NONE,
'Do not persist execution results to storage.'
);
}

/**
Expand All @@ -61,4 +72,20 @@ public function setTimeline(Timeline $timeline)
{
$this->timeline = $timeline;
}

/**
* @return StorageInterface
*/
public function getStorage()
{
return $this->storage;
}

/**
* @param StorageInterface $storage
*/
public function setStorage($storage)
{
$this->storage = $storage;
}
}
6 changes: 5 additions & 1 deletion src/Command/Timeline/ExecuteCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ protected function execute(InputInterface $input, OutputInterface $output)
$canExecute = $this->getHelper('question')->ask($input, $output, new ConfirmationQuestion($question));
}
if ($canExecute) {
$this->getTimeline()->runSingle($version, $options);
$result = $this->getTimeline()->runSingle($version, $options);
if ($result) {
$version = $result;
$this->getStorage()->update($version);
}
$output->writeln("Version <info>{$version->getId()}</info> migrated <info>$direction</info> successfully.");
}
}
Expand Down
31 changes: 29 additions & 2 deletions src/Command/Timeline/MigrateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
use Baleen\Migrations\Event\Timeline\MigrationEvent;
use Baleen\Migrations\Migration\Options;
use Baleen\Migrations\Timeline;
use Baleen\Migrations\Version;
use Baleen\Migrations\Version\Collection\MigratedVersions;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -51,6 +53,9 @@ class MigrateCommand extends AbstractTimelineCommand
/** @var ProgressBar */
protected $progress;

/** @var bool */
protected $saveChanges = true;

/** @var array */
protected $strategies = [
Options::DIRECTION_UP => 'upTowards',
Expand All @@ -61,6 +66,9 @@ class MigrateCommand extends AbstractTimelineCommand
/** @var bool */
protected $trackProgress = true;

/** @var string */
protected $directionPhrase = 'Migrating to';

/**
* @inheritdoc
*/
Expand Down Expand Up @@ -91,16 +99,19 @@ public function configure()
protected function execute(InputInterface $input, OutputInterface $output)
{
$targetArg = $input->getArgument(self::ARG_TARGET);
$this->saveChanges = !$input->getOption(self::OPT_NO_STORAGE);
$strategy = $this->getStrategyOption($input);

$options = new Options(Options::DIRECTION_UP); // this value will get replaced by timeline later
$options->setDryRun($input->getOption(self::OPT_DRY_RUN));
$options->setExceptionOnSkip(false);

$this->trackProgress = ($output->getVerbosity() !== OutputInterface::VERBOSITY_QUIET)
&& !$input->getOption(self::OPT_NOPROGRESS);

$this->attachEvents($output);

/** @var Version\Collection\LinkedVersions $results */
$this->getTimeline()->$strategy($targetArg, $options);
}

Expand All @@ -118,6 +129,20 @@ protected function attachEvents(OutputInterface $output)
$dispatcher->addListener(EventInterface::MIGRATION_BEFORE, [$this, 'onMigrationBefore']);
$dispatcher->addListener(EventInterface::MIGRATION_AFTER, [$this, 'onMigrationAfter']);
}

if ($this->saveChanges) {
$dispatcher->addListener(EventInterface::MIGRATION_AFTER, [$this, 'saveVersionListener']);
}
}

/**
* saveVersionListener
* @param MigrationEvent $event
*/
public function saveVersionListener(MigrationEvent $event)
{
$version = $event->getVersion();
$this->getStorage()->update($version);
}

/**
Expand Down Expand Up @@ -155,8 +180,10 @@ public function onMigrationAfter(MigrationEvent $event)
public function onCollectionBefore(CollectionEvent $event)
{
$target = $event->getTarget();

$this->output->writeln(sprintf(
'<info>[START]</info> Migrating towards <comment>%s</comment>:',
'<info>[START]</info> Migrating %s to <comment>%s</comment>:',
$event->getOptions()->isDirectionUp() ? 'up' : 'down',
$target->getId()
));
if ($this->trackProgress) {
Expand All @@ -175,7 +202,7 @@ public function onCollectionAfter()
$this->progress->finish();
$this->output->writeln(''); // new line after progress bar
}
$this->output->writeln('<info>[END]</info> All done!');
$this->output->writeln('<info>[END]</info>');
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/Container/ServiceProvider/DefaultProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public function register()
->invokeMethod('setStorage', [StorageProvider::SERVICE_STORAGE]);

$container->inflector(AbstractTimelineCommand::class)
->invokeMethod('setTimeline', [TimelineProvider::SERVICE_TIMELINE]);
->invokeMethod('setTimeline', [TimelineProvider::SERVICE_TIMELINE])
->invokeMethod('setStorage', [StorageProvider::SERVICE_STORAGE]);

$container->inflector(InitCommand::class)
->invokeMethod('setConfigStorage', [AppConfigProvider::SERVICE_CONFIG_STORAGE]);
Expand Down
76 changes: 62 additions & 14 deletions test/Command/Timeline/MigrateCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ public function testConfigure()
* testExecute
* @param $verbosity
* @param $noProgress
* @param $noStorage
* @dataProvider executeProvider
*/
public function testExecute($verbosity, $noProgress)
public function testExecute($verbosity, $noProgress, $noStorage)
{
// values don't matter here
$strategy = 'both';
Expand All @@ -90,13 +91,15 @@ public function testExecute($verbosity, $noProgress)

$this->input->shouldReceive('getArgument')->with(MigrateCommand::ARG_TARGET)->once()->andReturn($target);
$this->input->shouldReceive('getOption')->with(MigrateCommand::OPT_DRY_RUN)->once()->andReturn($dryRun);
$this->input->shouldReceive('getOption')->with(MigrateCommand::OPT_NO_STORAGE)->once()->andReturn($noStorage);
$this->instance->shouldReceive('getStrategyOption')->with($this->input)->andReturn($strategy);
$this->instance->shouldReceive('attachEvents')->once()->with($this->output);
$this->instance->shouldReceive('getTimeline->' . $strategy)->once()->with($target, m::type(Options::class));

$this->execute();

$this->assertEquals($shouldTrackProgress, $this->getPropVal('trackProgress', $this->instance));
$this->assertEquals(!$noStorage, $this->getPropVal('saveChanges', $this->instance));
}

/**
Expand All @@ -112,7 +115,8 @@ public function executeProvider()
OutputInterface::VERBOSITY_VERY_VERBOSE,
OutputInterface::VERBOSITY_DEBUG,
];
return $this->combinations([$verbosities, [true, false]]);
$trueFalse = [true, false];
return $this->combinations([$verbosities, $trueFalse, $trueFalse]);
}

/**
Expand Down Expand Up @@ -149,21 +153,26 @@ public function getStrategyOptionProvider()
*/
public function testOnCollectionAfter()
{
$this->output->shouldReceive('writeln')->with('/done/')->once();
$this->output->shouldReceive('writeln')->with('/END/')->once();
$this->setPropVal('output', $this->output, $this->instance);
$this->invokeMethod('onCollectionAfter', $this->instance);
}

/**
* testOnCollectionBefore
* @param bool $trackProgress
* @param bool $isDirectionUp
* @dataProvider onCollectionBeforeProvider
*/
public function testOnCollectionBefore($trackProgress = true)
public function testOnCollectionBefore($trackProgress = true, $isDirectionUp = true)
{
$target = new Version('v10');
/** @var m\Mock|CollectionEvent $event */
$event = m::mock(CollectionEvent::class);
$event->shouldReceive(['getTarget' => $target])->once();
$event->shouldReceive([
'getTarget' => $target,
'getOptions->isDirectionUp' => $isDirectionUp,
])->once();
$this->output->shouldReceive('writeln')->with('/' . $target->getId() . '/')->once();
$this->setPropVal('output', $this->output, $this->instance);

Expand All @@ -182,11 +191,14 @@ public function testOnCollectionBefore($trackProgress = true)
$this->invokeMethod('onCollectionBefore', $this->instance, [$event]);
}

public function trackProgressProvider()
/**
* onCollectionBeforeProvider
* @return array
*/
public function onCollectionBeforeProvider()
{
return [
[true], [false]
];
$trueFalse = [true, false];
return $this->combinations([$trueFalse, $trueFalse]);
}

/**
Expand All @@ -205,17 +217,53 @@ public function testOnMigrationBefore()
$this->invokeMethod('onMigrationBefore', $this->instance, [$event]);
}

public function testAttachEvents($verbosity = 1)
/**
* testAttachEvents
* @param int $verbosity
* @param $saveChanges
* @dataProvider attachEventsProvider
*/
public function testAttachEvents($verbosity, $saveChanges)
{
$dispatcher = m::mock(EventDispatcher::class);
$this->instance->shouldReceive('getTimeline->getEventDispatcher')->once()->andReturn($dispatcher);
$this->setPropVal('saveChanges', $saveChanges, $this->instance);
$this->output->shouldReceive('getVerbosity')->andReturn($verbosity);
$counts = [
EventInterface::MIGRATION_BEFORE => 0,
EventInterface::MIGRATION_AFTER => 0,
EventInterface::COLLECTION_BEFORE => 0,
EventInterface::COLLECTION_AFTER => 0,
];
if ($verbosity >= OutputInterface::VERBOSITY_NORMAL) {
$dispatcher->shouldReceive('addListener')->once()->with(EventInterface::MIGRATION_BEFORE, m::any());
$dispatcher->shouldReceive('addListener')->once()->with(EventInterface::MIGRATION_AFTER, m::any());
$dispatcher->shouldReceive('addListener')->once()->with(EventInterface::COLLECTION_BEFORE, m::any());
$dispatcher->shouldReceive('addListener')->once()->with(EventInterface::COLLECTION_AFTER, m::any());
$counts = [
EventInterface::MIGRATION_BEFORE => 1,
EventInterface::MIGRATION_AFTER => 1,
EventInterface::COLLECTION_BEFORE => 1,
EventInterface::COLLECTION_AFTER => 1,
];
}
if ($saveChanges) {
$counts[EventInterface::MIGRATION_AFTER] += 1;
}
foreach ($counts as $event => $count) {
$dispatcher->shouldReceive('addListener')->times($count)->with($event, m::any());
}
$this->invokeMethod('attachEvents', $this->instance, [$this->output]);
}

/**
* attachEventsProvider
* @return array
*/
public function attachEventsProvider()
{
$trueFalse = [true, false];
$verbosities = [
OutputInterface::VERBOSITY_QUIET,
OutputInterface::OUTPUT_NORMAL,
OutputInterface::VERBOSITY_VERY_VERBOSE,
];
return $this->combinations([$verbosities, $trueFalse]);
}
}

0 comments on commit 4d75275

Please sign in to comment.