Skip to content

Commit

Permalink
Merge pull request CakeDC#181 from cakephp/seed-command
Browse files Browse the repository at this point in the history
Seed command
  • Loading branch information
lorenzo committed Jan 10, 2016
2 parents c5960e3 + 3e00380 commit 04f969b
Show file tree
Hide file tree
Showing 15 changed files with 548 additions and 15 deletions.
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,47 @@ If no length is specified, lengths for certain columns are defaulted:
- *string*: `255`
- *integer*: `11`
- *biginteger*: `20`

### Seeding your database

As of 1.5.5, you can use the ``migrations`` shell to seed your database. This leverages the [Phinx library seed feature](http://docs.phinx.org/en/latest/seeding.html).
By default, seed files will be looked for in the ``config/Seeds`` directory of your application.
Please make sure you follow [Phinx instructions to build your seed files](http://docs.phinx.org/en/latest/seeding.html#creating-a-new-seed-class).

As for migrations, a ``bake`` interface is provided for seed files:

```bash
# This will create a ArticlesSeed.php file in the directory config/Seeds of your application
# By default, the table the seed will try to alter is the "tableized" version of the seed filename
bin/cake bake seed Articles

# You specify the name of the table the seed files will alter by using the ``--table`` option
bin/cake bake seed Articles --table my_articles_table

# You can specify a plugin to bake into
bin/cake bake seed Articles --plugin PluginName

# You can specify an alternative connection when generating a seeder.
bin/cake bake seed Articles --connection connection
```

To seed your database, you can use the ``seed`` subcommand:

```bash
# Without parameters, the seed subcommand will run all available seeders in the target directory, in alphabetical order.
bin/cake migrations seed

# You can specify only one seeder to be run using the `--seed` option
bin/cake migrations seed --seed ArticlesSeed

# You can run seeders from an alternative directory
bin/cake migrations seed --source AlternativeSeeds

# You can run seeders from a plugin
bin/cake migrations seed --plugin PluginName

# You can run seeders from a specific connection
bin/cake migrations seed --connection connection
```

Be aware that, as opposed to migrations, seeders are not tracked, which means that the same seeder can be applied multiple times.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"require": {
"php": ">=5.4",
"robmorgan/phinx": "~0.5.0",
"cakephp/cakephp": "~3.1,3.2.*"
"cakephp/cakephp": "~3.1 || 3.2.*"
},
"require-dev": {
"phpunit/phpunit": "*",
Expand Down
60 changes: 60 additions & 0 deletions src/Command/Seed.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php
/**
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Migrations\Command;

use Cake\Event\EventDispatcherTrait;
use Migrations\ConfigurationTrait;
use Phinx\Console\Command\SeedRun;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class Seed extends SeedRun
{

use ConfigurationTrait {
execute as parentExecute;
}
use EventDispatcherTrait;

/**
* {@inheritdoc}
*/
protected function configure()
{
$this->setName('seed')
->setDescription('Seed the database with data')
->setHelp('runs all available migrations, optionally up to a specific version')
->addOption('--seed', null, InputOption::VALUE_REQUIRED, 'What is the name of the seeder?')
->addOption('--plugin', '-p', InputOption::VALUE_REQUIRED, 'The plugin containing the migrations')
->addOption('--connection', '-c', InputOption::VALUE_REQUIRED, 'The datasource connection to use')
->addOption('--source', '-s', InputOption::VALUE_REQUIRED, 'The folder where migrations are in');
}

/**
* Overrides the action execute method in order to vanish the idea of environments
* from phinx. CakePHP does not believe in the idea of having in-app environments
*
* @param \Symfony\Component\Console\Input\InputInterface $input the input object
* @param \Symfony\Component\Console\Output\OutputInterface $output the output object
* @return mixed
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$event = $this->dispatchEvent('Migration.beforeSeed');
if ($event->isStopped()) {
return $event->result;
}
$this->parentExecute($input, $output);
$this->dispatchEvent('Migration.afterSeed');
}
}
31 changes: 23 additions & 8 deletions src/ConfigurationTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Cake\Core\Plugin;
use Cake\Datasource\ConnectionManager;
use Cake\Utility\Inflector;
use Migrations\Command\Seed;
use Phinx\Config\Config;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
Expand Down Expand Up @@ -55,21 +56,34 @@ public function getConfig($forceRefresh = false)
return $this->configuration;
}

$folder = 'Migrations';
if ($this->input->getOption('source')) {
$folder = $this->input->getOption('source');
$migrationsFolder = 'Migrations';
$seedsFolder = 'Seeds';

$source = $this->input->getOption('source');
if ($source) {
if ($this instanceof Seed) {
$seedsFolder = $source;
} else {
$migrationsFolder = $source;
}
}

$dir = ROOT . DS . 'config' . DS . $folder;
$migrationsPath = ROOT . DS . 'config' . DS . $migrationsFolder;
$seedsPath = ROOT . DS . 'config' . DS . $seedsFolder;
$plugin = null;

if ($this->input->getOption('plugin')) {
$plugin = $this->input->getOption('plugin');
$dir = Plugin::path($plugin) . 'config' . DS . $folder;
$migrationsPath = Plugin::path($plugin) . 'config' . DS . $migrationsFolder;
$seedsPath = Plugin::path($plugin) . 'config' . DS . $seedsFolder;
}

if (!is_dir($migrationsPath)) {
mkdir($migrationsPath, 0777, true);
}

if (!is_dir($dir)) {
mkdir($dir, 0777, true);
if (!is_dir($seedsPath)) {
mkdir($seedsPath, 0777, true);
}

$plugin = $plugin ? Inflector::underscore($plugin) . '_' : '';
Expand All @@ -81,7 +95,8 @@ public function getConfig($forceRefresh = false)
$adapterName = $this->getAdapterName($connectionConfig['driver']);
$config = [
'paths' => [
'migrations' => $dir
'migrations' => $migrationsPath,
'seeds' => $seedsPath,
],
'environments' => [
'default_migration_table' => $plugin . 'phinxlog',
Expand Down
1 change: 1 addition & 0 deletions src/MigrationsDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ public function __construct($version)
$this->add(new Command\Rollback());
$this->add(new Command\Status());
$this->add(new Command\MarkMigrated());
$this->add(new Command\Seed());
}
}
1 change: 1 addition & 0 deletions src/Shell/MigrationsShell.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public function getOptionParser()
->addOption('target', ['short' => 't'])
->addOption('connection', ['short' => 'c'])
->addOption('source', ['short' => 's'])
->addOption('seed')
->addOption('ansi')
->addOption('no-ansi')
->addOption('version', ['short' => 'V'])
Expand Down
16 changes: 14 additions & 2 deletions src/Shell/Task/SeedTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class SeedTask extends SimpleBakeTask
*
* @var string
*/
public $pathFragment = 'Seed/';
public $pathFragment = 'config/Seeds/';

/**
* {@inheritDoc}
Expand All @@ -44,7 +44,19 @@ public function name()
*/
public function fileName($name)
{
return Inflector::classify($this->args[0]) . 'Seed.php';
return Inflector::camelize($name) . 'Seed.php';
}

/**
* {@inheritDoc}
*/
public function getPath()
{
$path = ROOT . DS . $this->pathFragment;
if (isset($this->plugin)) {
$path = $this->_pluginPath($this->plugin) . $this->pathFragment;
}
return str_replace('/', DS, $path);
}

/**
Expand Down
2 changes: 0 additions & 2 deletions src/Template/Bake/Seed/seed.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
*/
%>
<?php
namespace <%= $namespace %>\Seed;

use Phinx\Seed\AbstractSeed;

/**
Expand Down
Loading

0 comments on commit 04f969b

Please sign in to comment.