Merge pull request #19 from webNeat/bugfixes

Preparing Version 1.2.0
This commit is contained in:
Amine Ben hammou 2017-01-12 17:02:38 +01:00 committed by GitHub
commit 6e7d3fbf95
26 changed files with 330 additions and 254 deletions

3
.gitignore vendored
View File

@ -5,4 +5,5 @@
tests/_output/*
lumen-test/app
lumen-test/database
lumen-test/database
lumen-test/tests/tmp

View File

@ -257,7 +257,7 @@ More then that, you can generate multiple resources with only one command ! [Cli
The `wn:model` command is used to generate a model class based on Eloquent. It has the following syntax:
```
wn:model name [--fillable=...] [--dates=...] [--has-many=...] [--has-one=...] [--belongs-to=...] [--belongs-to-many=...] [--rules=...] [--path=...]
wn:model name [--fillable=...] [--dates=...] [--has-many=...] [--has-one=...] [--belongs-to=...] [--belongs-to-many=...] [--rules=...] [--path=...] [--force=true]
```
- **name**: the name of the model.
@ -357,12 +357,18 @@ gives:
];
```
- **--force**: tells the generator to override the existing file. By default, if the model file already exists, it will not be overriden and the output will be something like:
```
TestingModel model already exists; use --force option to override it !
```
### Migration Generator
The `wn:migration` command is used to generate a migration to create a table with schema. It has the following syntax:
```
wn:migration table [--schema=...] [--keys=...] [--file=...]
wn:migration table [--schema=...] [--keys=...] [--force=true] [--file=...]
```
- **table**: the name of the table to create.
@ -427,7 +433,7 @@ $table->foreign('user_id')
The `wn:pivot-table` command is used to generate a migration to create a pivot table between two models. It has the following syntax:
```
wn:pivot-table model1 model2 [--file=...]
wn:pivot-table model1 model2 [--force=true] [--file=...]
```
- **model1** and **model2**: names of the two models (or the two tables if the models don't follow the naming conventions)
@ -487,12 +493,14 @@ There are two commands for controllers. The first one is `wn:controller:rest-act
Note that the trait doesn't use the common used methods on Laravel (like index, store, ...) to avoid conflicts. Which enables you to use this trait with controllers you already have in your application.
The second command is `wn:controller` which actually generates the controller. The syntax of this command is `wn:controller model [--no-routes]`.
The second command is `wn:controller` which actually generates the controller. The syntax of this command is `wn:controller model [--no-routes] [--force=true]`.
- **model**: Name of the model (with namespace if not `App`).
- **--no-routes**: Since routes are generated by default for the controller, this option is used to tell the generator "do not generate routes !".
- **--force**: tells the generator to override the existing file.
`php artisan wn:controller Task --no-routes` gives:
@ -513,12 +521,14 @@ class TasksController extends Controller {
The `wn:route` command is used to generate RESTfull routes for a controller. It has the following syntax:
`wn:route resource [--controller=...]`
`wn:route resource [--controller=...] [--force=true]`
- **resource**: the resource name to use in the URLs.
- **--controller**: the corresponding controller. If missing it's deducted from the resource name.
- **--force**: tells the generator to override the existing file.
`php artisan wn:route project-type` adds the following routes:
```php
@ -531,7 +541,7 @@ $app->delete('project-type/{id}', 'ProjectTypesController@remove');
### Resource Generator
The `wn:resource` command makes it very easy to generate a RESTful resource. It generates a model, migration, controller and routes. The syntax is : `wn:resource name fields [--has-many=...] [--has-one=...] [--belongs-to=...] [--migration-file=...]`
The `wn:resource` command makes it very easy to generate a RESTful resource. It generates a model, migration, controller and routes. The syntax is : `wn:resource name fields [--has-many=...] [--has-one=...] [--belongs-to=...] [--migration-file=...] [--path=...] [--force=true]`
- **name**: the name of the resource used in the URLs and to determine the model, table and controller names.
@ -555,18 +565,24 @@ The `wn:resource` command makes it very easy to generate a RESTful resource. It
- **--migration-file**: passed to the `wn:migration` as the `--file` option.
- **--path**: Defines where to store the model file as well as its namespace.
- **--force**: tells the generator to override the existing file.
### Multiple Resources From File
The `wn:resources` (note the "s" in "resources") command takes the generation process to an other level by parsing a file and generating multiple resources based on it. The syntax is
```
wn:resources filename
wn:resources filename [--path=...] [--force=true]
```
This generator is smart enough to add foreign keys automatically when finding a belongsTo relation. It also generates pivot tables for belongsToMany relations automatically.
The file given to the command should be a valid YAML file ( for the moment, support of other types like XML or JSON could be added in the future). An example is the following:
- **--path**: Defines where to store the model files as well as their namespace.
```yaml
---
Store:
@ -606,6 +622,42 @@ To test the generators, I included a fresh lumen installation under the folder `
## Development Notes
- **Comming versions**
- **Seeder and Test generators**
- Requested Feature: [Disabling timestamps](https://github.com/webNeat/lumen-generators/issues/15)
- Requested Feature: [Custom Templates](https://github.com/webNeat/lumen-generators/issues/13)
- **Version 1.2.0**
- Tests fixed.
- Bug fixed: [Undefined index: factory](https://github.com/webNeat/lumen-generators/issues/14)
- Feature added: [Check if file already exists before generating it](https://github.com/webNeat/lumen-generators/issues/11)
- Feature added: [Support for additional columns like nullableTimestamps() and softDeletes() in migrations](https://github.com/webNeat/lumen-generators/issues/12)
- Feature added: [Specifying namespace for `wn:resource` and `wn:resources`](https://github.com/webNeat/lumen-generators/issues/18)
- **Version 1.1.1**
- Pivot table generation from the `wn:resources` command bug fixed.
- **Version 1.1.0**
- Pivot table generator added.
- belongsToMany relationship added to model generator.
- Multiple resources generator adds foreign keys for belongsTo relationships automatically.
- Multiple resources generator adds pivot tables for belongsToMany relationships automatically.
- Generated migrations file names changed to be supported by `migrate` command.
- **Version 1.0.0**
- Model Generator
@ -620,22 +672,6 @@ To test the generators, I included a fresh lumen installation under the folder `
- Multiple Resources From File
- **Version 1.1.0**
- Pivot table generator added.
- belongsToMany relationship added to model generator.
- Multiple resources generator adds foreign keys for belongsTo relationships automatically.
- Multiple resources generator adds pivot tables for belongsToMany relationships automatically.
- Generated migrations file names changed to be supported by `migrate` command.
- **Version 1.1.1**
- Pivot table generation from the `wn:resources` command bug fixed.
## Contributing
Pull requests are welcome :D

View File

@ -14,7 +14,7 @@
"fzaninotto/faker": "~1.0",
"phpspec/phpspec": "2.0.0",
"codeception/codeception": "2.0.0",
"wn/lumen-generators": "@dev"
"wn/lumen-generators": "dev-bugfixes"
},
"autoload": {
"psr-4": {

View File

@ -19,24 +19,3 @@ $factory->define(App\User::class, function ($faker) {
'remember_token' => str_random(10),
];
});
/**
* Factory definition for model App\Task.
*/
$factory->define(App\Task::class, function ($faker) {
return [
// Fields here
];
});
/**
* Factory definition for model App\TaskCategory.
*/
$factory->define(App\TaskCategory::class, function ($faker) {
return [
'name' => $faker->word,
'descr' => $faker->paragraph,
'due' => $faker->date,
'project_id' => $faker->key,
'user_id' => $faker->key,
];
});

22
lumen-test/models.yml Normal file
View File

@ -0,0 +1,22 @@
---
Post:
belongsToMany: tags
fields:
title:
schema: string
rules: required
tags: fillable
content:
schema: text nullable
tags: fillable
published_at:
schema: date
rules: date
tags: date fillable
Tag:
belongsToMany: posts
fields:
name:
schema: string unique
rules: required
tags: fillable

View File

@ -38,12 +38,12 @@ $I->wantTo('generate model factories with fields');
$I->runShellCommand('php artisan wn:factory "App\Task" --fields="title:sentence(3),description:paragraph(3),due:date,hidden:boolean"');
$I->seeInShellOutput('App\Task factory generated');
$I->openFile('./database/factories/ModelFactory.php');
$I->seeInThisFile("
'title' => \$faker->sentence(3),
'description' => \$faker->paragraph(3),
'due' => \$faker->date,
'hidden' => \$faker->boolean,
");
$I->seeInThisFile(
" 'title' => \$faker->sentence(3)," . PHP_EOL .
" 'description' => \$faker->paragraph(3)," . PHP_EOL .
" 'due' => \$faker->date," . PHP_EOL .
" 'hidden' => \$faker->boolean,"
);
$I->writeToFile('./database/factories/ModelFactory.php', "<?php
/*

View File

@ -69,11 +69,24 @@ $I->runShellCommand('php artisan wn:migration tasks --file=create_tasks --keys="
$I->seeInShellOutput('tasks migration generated');
$I->seeFileFound('./database/migrations/create_tasks.php');
$I->openFile('./database/migrations/create_tasks.php');
$I->seeInThisFile('$table->foreign(\'category_type_id\')
->references(\'id\')
->on(\'category_types\');');
$I->seeInThisFile("\$table->foreign('user_id')
->references('identifier')
->on('members')
->onDelete('cascade');");
$I->deleteFile('./database/migrations/create_tasks.php');
$I->seeInThisFile(
"\$table->foreign('category_type_id')\n".
" ->references('id')\n".
" ->on('category_types');"
);
$I->seeInThisFile(
"\$table->foreign('user_id')\n".
" ->references('identifier')\n".
" ->on('members')". PHP_EOL .
" ->onDelete('cascade');");
$I->deleteFile('./database/migrations/create_tasks.php');
$I->wantTo('generate a migration with additional columns');
$I->runShellCommand('php artisan wn:migration tasks --file=create_tasks --add=softDeletes,nullableTimestamps');
$I->seeInShellOutput('tasks migration generated');
$I->seeFileFound('./database/migrations/create_tasks.php');
$I->openFile('./database/migrations/create_tasks.php');
$I->dontSeeInThisFile("\$table->timestamps();");
$I->seeInThisFile("\$table->softDeletes();");
$I->seeInThisFile("\$table->nullableTimestamps();");
$I->deleteFile('./database/migrations/create_tasks.php');

View File

@ -2,7 +2,7 @@
$I = new AcceptanceTester($scenario);
$I->wantTo('generate a model without fillable fields or dates');
$I->runShellCommand('php artisan wn:model TestingModel --path=tests/tmp');
$I->runShellCommand('php artisan wn:model TestingModel --path=tests/tmp --force=true');
$I->seeInShellOutput('TestingModel model generated');
$I->seeFileFound('./tests/tmp/TestingModel.php');
$I->openFile('./tests/tmp/TestingModel.php');
@ -25,18 +25,21 @@ class TestingModel extends Model {
}
');
$I->deleteFile('./tests/tmp/TestingModel.php');
$I->wantTo('generate a model with fillable fields');
$I->runShellCommand('php artisan wn:model TestingModel --fillable=name,title --path=tests/tmp');
$I->seeFileFound('./tests/tmp/TestingModel.php');
$I->openFile('./tests/tmp/TestingModel.php');
$I->seeInThisFile('protected $fillable = ["name", "title"];');
$I->deleteFile('./tests/tmp/TestingModel.php');
$I->wantTo('generate a model with dates fields');
$I->runShellCommand('php artisan wn:model TestingModel --dates=started_at --path=tests/tmp');
$I->seeFileFound('./tests/tmp/TestingModel.php');
$I->openFile('./tests/tmp/TestingModel.php');
$I->seeInThisFile('protected $dates = ["started_at"];');
$I->deleteFile('./tests/tmp/TestingModel.php');
$I->wantTo('generate a model with relations');
$I->runShellCommand('php artisan wn:model TestingModel --has-many=accounts --belongs-to="owner:App\User" --has-one=number:Phone --path=tests/tmp');
@ -60,17 +63,18 @@ $I->seeInThisFile('
return $this->hasOne("Tests\\Tmp\\Phone");
}
');
$I->deleteFile('./tests/tmp/TestingModel.php');
$I->wantTo('generate a model with validation rules');
$I->runShellCommand('php artisan wn:model TestingModel --rules="name=required age=integer|min:13 email=email|unique:users,email_address" --path=tests/tmp');
$I->seeFileFound('./tests/tmp/TestingModel.php');
$I->openFile('./tests/tmp/TestingModel.php');
$I->seeInThisFile('
public static $rules = [
"name" => "required",
"age" => "integer|min:13",
"email" => "email|unique:users,email_address",
];
');
$I->seeInThisFile(
" public static \$rules = [\n" .
" \"name\" => \"required\"," . PHP_EOL .
" \"age\" => \"integer|min:13\"," . PHP_EOL .
" \"email\" => \"email|unique:users,email_address\",\n".
" ];"
);
$I->deleteFile('./tests/tmp/TestingModel.php');

View File

@ -1,29 +1,29 @@
<?php
$I = new AcceptanceTester($scenario);
$I->wantTo('generate a pivot table seeder');
$I->runShellCommand('php artisan wn:pivot-seeder tasks ShortTag');
$I->seeInShellOutput('ShortTagTaskTableSeeder generated');
$I->openFile('./database/seeds/ShortTagTaskTableSeeder.php');
$I->seeInThisFile("
use Illuminate\Database\Seeder;
use Faker\Factory as Faker;
// $I->wantTo('generate a pivot table seeder');
// $I->runShellCommand('php artisan wn:pivot-seeder tasks ShortTag');
// $I->seeInShellOutput('ShortTagTaskTableSeeder generated');
// $I->openFile('./database/seeds/ShortTagTaskTableSeeder.php');
// $I->seeInThisFile("
// use Illuminate\Database\Seeder;
// use Faker\Factory as Faker;
class ShortTagTaskTableSeeder extends Seeder
{
public function run()
{
\$faker = Faker::create();
// class ShortTagTaskTableSeeder extends Seeder
// {
// public function run()
// {
// \$faker = Faker::create();
\$firstIds = DB::table('short_tags')->lists('id');
\$secondIds = DB::table('tasks')->lists('id');
// \$firstIds = DB::table('short_tags')->lists('id');
// \$secondIds = DB::table('tasks')->lists('id');
for(\$i = 0; \$i < 10; \$i++) {
DB::table('short_tag_task')->insert([
'short_tag_id' => \$faker->randomElement(\$firstIds),
'task_id' => \$faker->randomElement(\$secondIds)
]);
}
}
}");
$I->deleteFile('./database/seeds/ShortTagTaskTableSeeder.php');
// for(\$i = 0; \$i < 10; \$i++) {
// DB::table('short_tag_task')->insert([
// 'short_tag_id' => \$faker->randomElement(\$firstIds),
// 'task_id' => \$faker->randomElement(\$secondIds)
// ]);
// }
// }
// }");
// $I->deleteFile('./database/seeds/ShortTagTaskTableSeeder.php');

View File

@ -13,28 +13,29 @@ $I->seeInThisFile('namespace App;');
$I->seeInThisFile('class TaskCategory extends Model');
$I->seeInThisFile('protected $fillable = ["name", "descr", "due", "project_id", "user_id"];');
$I->seeInThisFile('protected $dates = ["due"];');
$I->seeInThisFile('public static $rules = [
"name" => "requied",
"project_id" => "required|numeric",
"user_id" => "required|numeric",
];');
$I->seeInThisFile('
public function tags()
$I->seeInThisFile(
"public static \$rules = [\n".
" \"name\" => \"requied\"," . PHP_EOL .
" \"project_id\" => \"required|numeric\"," . PHP_EOL .
" \"user_id\" => \"required|numeric\",\n".
" ];");
$I->seeInThisFile(
' public function tags()
{
return $this->hasMany("App\Tag");
}
public function tasks()
}');
$I->seeInThisFile(
' public function tasks()
{
return $this->hasMany("App\Task");
}
public function project()
}');
$I->seeInThisFile(
' public function project()
{
return $this->belongsTo("App\Project");
}
public function creator()
}');
$I->seeInThisFile(
' public function creator()
{
return $this->belongsTo("App\User");
}');
@ -46,21 +47,20 @@ $I->seeFileFound('./database/migrations/create_task_categories.php');
$I->openFile('./database/migrations/create_task_categories.php');
$I->seeInThisFile('class CreateTaskCategoriesTable extends Migration');
$I->seeInThisFile('Schema::create(\'task_categories\', function(Blueprint $table) {
$table->increments(\'id\');
$table->string(\'name\')->unique();
$table->text(\'descr\')->nullable();
$table->timestamp(\'due\');
$table->integer(\'project_id\')->unsigned();
$table->integer(\'user_id\')->unsigned();
$table->foreign(\'project_id\')
->references(\'id\')
->on(\'projects\');
$table->foreign(\'user_id\')
->references(\'id\')
->on(\'users\');
$table->timestamps();
});');
$I->seeInThisFile("Schema::create('task_categories', function(Blueprint \$table) {\n".
" \$table->increments('id');\n".
" \$table->string('name')->unique();" . PHP_EOL .
" \$table->text('descr')->nullable();" . PHP_EOL .
" \$table->timestamp('due');" . PHP_EOL .
" \$table->integer('project_id')->unsigned();" . PHP_EOL.
" \$table->integer('user_id')->unsigned();\n" .
" \$table->foreign('project_id')\n".
" ->references('id')\n".
" ->on('projects');" . PHP_EOL .
" \$table->foreign('user_id')\n".
" ->references('id')\n".
" ->on('users');\n".
" \$table->timestamps();");
$I->deleteFile('./database/migrations/create_task_categories.php');
@ -110,9 +110,9 @@ $app->get("/", function () use ($app) {
');
// Checking model factory
$I->openFile('./database/factories/ModelFactory.php');
// $I->seeInThisFile("
// /**
// $I->openFile('./database/factories/ModelFactory.php');
// $I->seeInThisFile(
// "/**
// * Factory definition for model App\TaskCategory.
// */
// \$factory->define(App\TaskCategory::class, function (\$faker) {
@ -146,15 +146,15 @@ $I->writeToFile('./database/factories/ModelFactory.php', "<?php
");
// Checking database seeder
$I->openFile('./database/seeds/TaskCategoriesTableSeeder.php');
$I->seeInThisFile('
use Illuminate\Database\Seeder;
// $I->openFile('./database/seeds/TaskCategoriesTableSeeder.php');
// $I->seeInThisFile('
// use Illuminate\Database\Seeder;
class TaskCategoriesTableSeeder extends Seeder
{
public function run()
{
factory(App\TaskCategory::class, 10)->create();
}
}');
$I->deleteFile('./database/seeds/TaskCategoriesTableSeeder.php');
// class TaskCategoriesTableSeeder extends Seeder
// {
// public function run()
// {
// factory(App\TaskCategory::class, 10)->create();
// }
// }');
// $I->deleteFile('./database/seeds/TaskCategoriesTableSeeder.php');

View File

@ -1,34 +1,34 @@
<?php
$I = new AcceptanceTester($scenario);
$I->wantTo('generate a seeder with default options');
$I->runShellCommand('php artisan wn:seeder "App\Task"');
$I->seeInShellOutput('TasksTableSeeder generated');
$I->openFile('./database/seeds/TasksTableSeeder.php');
$I->seeInThisFile('
use Illuminate\Database\Seeder;
// $I->wantTo('generate a seeder with default options');
// $I->runShellCommand('php artisan wn:seeder "App\Task"');
// $I->seeInShellOutput('TasksTableSeeder generated');
// $I->openFile('./database/seeds/TasksTableSeeder.php');
// $I->seeInThisFile('
// use Illuminate\Database\Seeder;
class TasksTableSeeder extends Seeder
{
public function run()
{
factory(App\Task::class, 10)->create();
}
}');
$I->deleteFile('./database/seeds/TasksTableSeeder.php');
// class TasksTableSeeder extends Seeder
// {
// public function run()
// {
// factory(App\Task::class, 10)->create();
// }
// }');
// $I->deleteFile('./database/seeds/TasksTableSeeder.php');
$I->wantTo('generate a seeder with custom options');
$I->runShellCommand('php artisan wn:seeder "App\Category" --count=25');
$I->seeInShellOutput('CategoriesTableSeeder generated');
$I->openFile('./database/seeds/CategoriesTableSeeder.php');
$I->seeInThisFile('
use Illuminate\Database\Seeder;
// $I->wantTo('generate a seeder with custom options');
// $I->runShellCommand('php artisan wn:seeder "App\Category" --count=25');
// $I->seeInShellOutput('CategoriesTableSeeder generated');
// $I->openFile('./database/seeds/CategoriesTableSeeder.php');
// $I->seeInThisFile('
// use Illuminate\Database\Seeder;
class CategoriesTableSeeder extends Seeder
{
public function run()
{
factory(App\Category::class, 25)->create();
}
}');
$I->deleteFile('./database/seeds/CategoriesTableSeeder.php');
// class CategoriesTableSeeder extends Seeder
// {
// public function run()
// {
// factory(App\Category::class, 25)->create();
// }
// }');
// $I->deleteFile('./database/seeds/CategoriesTableSeeder.php');

View File

@ -1,17 +0,0 @@
<?php namespace Tests\Tmp;
use Illuminate\Database\Eloquent\Model;
class TestingModel extends Model
{
protected $fillable = [];
protected $dates = [];
public static $rules = [
// Validation rules
];
// Relationships
}

View File

@ -8,14 +8,14 @@ use Wn\Generators\Template\TemplateLoader;
class BaseCommand extends Command {
protected $fs;
protected $templates;
public function __construct(Filesystem $fs)
{
parent::__construct();
$this->fs = $fs;
$this->templates = new TemplateLoader($fs);
$this->argumentFormatLoader = new ArgumentFormatLoader($fs);
@ -31,10 +31,15 @@ class BaseCommand extends Command {
return new ArgumentParser($format);
}
protected function save($content, $path)
protected function save($content, $path, $name, $force = false)
{
if (!$force && $this->fs->exists($path) && $this->input->hasOption('force') && !$this->option('force')) {
$this->info("{$name} already exists; use --force option to override it !");
return;
}
$this->makeDirectory($path);
$this->fs->put($path, $content);
$this->info("{$name} generated !");
}
protected function makeDirectory($path)
@ -44,4 +49,9 @@ class BaseCommand extends Command {
}
}
protected function spaces($n)
{
return str_repeat(' ', $n);
}
}

View File

@ -5,7 +5,9 @@ class ControllerCommand extends BaseCommand {
protected $signature = 'wn:controller
{model : Name of the model (with namespace if not App)}
{--no-routes= : without routes}';
{--no-routes= : without routes}
{--force= : override the existing files}
';
protected $description = 'Generates RESTful controller using the RESTActions trait';
@ -28,9 +30,7 @@ class ControllerCommand extends BaseCommand {
])
->get();
$this->save($content, "./app/Http/Controllers/{$controller}.php");
$this->info("{$controller} generated !");
$this->save($content, "./app/Http/Controllers/{$controller}.php", "{$controller}");
if(! $this->option('no-routes')){
$this->call('wn:route', [
@ -39,5 +39,5 @@ class ControllerCommand extends BaseCommand {
]);
}
}
}

View File

@ -3,7 +3,8 @@
class ControllerRestActionsCommand extends BaseCommand {
protected $signature = 'wn:controller:rest-actions';
protected $signature = 'wn:controller:rest-actions
{--force= : override the existing files}';
protected $description = 'Generates REST actions trait to use into controllers';
@ -11,9 +12,7 @@ class ControllerRestActionsCommand extends BaseCommand {
{
$content = $this->getTemplate('controller/rest-actions')->get();
$this->save($content, "./app/Http/Controllers/RESTActions.php");
$this->info("REST actions trait generated !");
$this->save($content, "./app/Http/Controllers/RESTActions.php", "REST actions trait");
}
}

View File

@ -7,7 +7,9 @@ class FactoryCommand extends BaseCommand {
{model : full qualified name of the model.}
{--fields= : the fields to generate.}
{--file= : the factories file.}
{--parsed : tells the command that arguments have been already parsed. To use when calling the command from an other command and passing the parsed arguments and options}';
{--parsed : tells the command that arguments have been already parsed. To use when calling the command from an other command and passing the parsed arguments and options}
{--force= : override the existing files}
';
protected $description = 'Generates a model factory';
@ -26,9 +28,7 @@ class FactoryCommand extends BaseCommand {
])
->get();
$this->save($content, $file);
$this->info("{$model} factory generated !");
$this->save($content, $file, "{$model} factory", true);
}
protected function getFile()

View File

@ -6,10 +6,12 @@ class MigrationCommand extends BaseCommand {
protected $signature = 'wn:migration
{table : The table name.}
{--schema= : the schema.}
{--add= : specifies additional columns like softDeletes, rememberToken and nullableTimestamps.}
{--keys= : foreign keys.}
{--file= : name of the migration file (to use only for testing purpose).}
{--parsed : tells the command that arguments have been already parsed. To use when calling the command from an other command and passing the parsed arguments and options}
';
{--force= : override the existing files}
';
// {action : One of create, add, remove or drop options.}
// The action is only create for the moment
@ -25,6 +27,7 @@ class MigrationCommand extends BaseCommand {
'table' => $table,
'name' => $name,
'schema' => $this->getSchema(),
'additionals' => $this->getAdditionals(),
'constraints' => $this->getConstraints()
])
->get();
@ -34,16 +37,14 @@ class MigrationCommand extends BaseCommand {
$file = date('Y_m_d_His_') . snake_case($name) . '_table';
}
$this->save($content, "./database/migrations/{$file}.php");
$this->info("{$table} migration generated !");
$this->save($content, "./database/migrations/{$file}.php", "{$table} migration");
}
protected function getSchema()
{
$schema = $this->option('schema');
if(! $schema){
return " // Schema declaration";
return $this->spaces(12) . "// Schema declaration";
}
$items = $schema;
@ -59,6 +60,23 @@ class MigrationCommand extends BaseCommand {
return implode(PHP_EOL, $fields);
}
protected function getAdditionals()
{
$additionals = $this->option('add');
if (empty($additionals)) {
$additionals = 'timestamps';
}
$additionals = explode(',', $additionals);
$lines = [];
foreach ($additionals as $add) {
$add = trim($add);
$lines[] = $this->spaces(12) . "\$table->{$add}();";
}
return implode(PHP_EOL, $lines);
}
protected function getFieldDeclaration($parts)
{
$name = $parts[0]['name'];
@ -74,7 +92,7 @@ class MigrationCommand extends BaseCommand {
{
$keys = $this->option('keys');
if(! $keys){
return " // Constraints declaration";
return $this->spaces(12) . "// Constraints declaration";
}
$items = $keys;
@ -127,5 +145,5 @@ class MigrationCommand extends BaseCommand {
return $constraint . ';';
}
}

View File

@ -13,7 +13,9 @@ class ModelCommand extends BaseCommand {
{--belongs-to-many= : belongsToMany relationships.}
{--rules= : fields validation rules.}
{--path=app : where to store the model php file.}
{--parsed : tells the command that arguments have been already parsed. To use when calling the command from an other command and passing the parsed arguments and options}';
{--parsed : tells the command that arguments have been already parsed. To use when calling the command from an other command and passing the parsed arguments and options}
{--force= : override the existing files}
';
protected $description = 'Generates a model class for a RESTfull resource';
@ -33,9 +35,7 @@ class ModelCommand extends BaseCommand {
])
->get();
$this->save($content, "./{$path}/{$name}.php");
$this->info("{$name} model generated !");
$this->save($content, "./{$path}/{$name}.php", "{$name} model");
}
protected function getAsArrayFields($arg, $isOption = true)

View File

@ -7,6 +7,7 @@ class PivotSeederCommand extends BaseCommand {
{model1 : Name of the first model or table}
{model2 : Name of the second model or table}
{--count=10 : number of elements to add in database.}
{--force= : override the existing files}
';
protected $description = 'Generates seeder for pivot table';
@ -29,9 +30,7 @@ class PivotSeederCommand extends BaseCommand {
])
->get();
$this->save($content, $file);
$this->info("{$name} generated !");
$this->save($content, $file, $name);
}
protected function getResources()
@ -39,7 +38,7 @@ class PivotSeederCommand extends BaseCommand {
$resources = array_map(function($arg) {
return snake_case(str_singular($this->argument($arg)));
}, ['model1', 'model2']);
sort($resources);
return $resources;

View File

@ -7,7 +7,8 @@ class PivotTableCommand extends BaseCommand {
{model1 : Name of the first model or table}
{model2 : Name of the second model or table}
{--file= : name of the migration file (to use only for testing purpose).}
';
{--force= : override the existing files}
';
protected $description = 'Generates creation migration for a pivot table';
@ -22,7 +23,8 @@ class PivotTableCommand extends BaseCommand {
'--schema' => $this->schema(),
'--keys' => $this->keys(),
'--file' => $this->option('file'),
'--parsed' => false
'--parsed' => false,
'--force' => $this->option('force')
]);
}
@ -31,7 +33,7 @@ class PivotTableCommand extends BaseCommand {
$this->tables = array_map(function($arg) {
return snake_case(str_singular($this->argument($arg)));
}, ['model1', 'model2']);
sort($this->tables);
}
@ -48,5 +50,5 @@ class PivotTableCommand extends BaseCommand {
return $table . '_id';
}, $this->tables));
}
}

View File

@ -11,8 +11,10 @@ class ResourceCommand extends BaseCommand {
{--belongs-to= : belongsTo relationships.}
{--belongs-to-many= : belongsToMany relationships.}
{--migration-file= : the migration file name.}
{--path=app : where to store the model file.}
{--parsed : tells the command that arguments have been already parsed. To use when calling the command from an other command and passing the parsed arguments and options}
';
{--force= : override the existing files}
';
protected $description = 'Generates a model, migration, controller and routes for RESTful resource';
@ -36,27 +38,30 @@ class ResourceCommand extends BaseCommand {
'--belongs-to' => $this->option('belongs-to'),
'--belongs-to-many' => $this->option('belongs-to-many'),
'--rules' => $this->rules(),
'--path' => 'app',
'--path' => $this->option('path'),
'--force' => $this->option('force'),
'--parsed' => true
]);
// generating the migration
$this->call('wn:migration', [
'table' => $tableName,
'--schema' => $this->schema(),
'--keys' => $this->migrationKeys(),
'--file' => $this->option('migration-file'),
'--force' => $this->option('force'),
'--parsed' => true
]);
// generating REST actions trait if doesn't exist
if(! $this->fs->exists('./app/Http/Controllers/RESTActions.php')){
$this->call('wn:controller:rest-actions');
}
// generating the controller and routes
$this->call('wn:controller', [
'model' => $modelName,
'--force' => $this->option('force'),
'--no-routes' => false
]);
@ -64,13 +69,14 @@ class ResourceCommand extends BaseCommand {
$this->call('wn:factory', [
'model' => 'App\\' . $modelName,
'--fields' => $this->factoryFields(),
'--force' => $this->option('force'),
'--parsed' => true
]);
// generating database seeder
$this->call('wn:seeder', [
'model' => 'App\\' . $modelName
]);
// $this->call('wn:seeder', [
// 'model' => 'App\\' . $modelName
// ]);
}
@ -95,13 +101,13 @@ class ResourceCommand extends BaseCommand {
],
'rules' => 'required|numeric',
'tags' => ['fillable', 'key'],
'factory' => 'key'
'factory' => 'key'
];
}, $this->foreignKeys()));
}
}
}
protected function fieldsHavingTag($tag)
{
return array_map(function($field){

View File

@ -6,7 +6,10 @@ use Symfony\Component\Yaml\Yaml;
class ResourcesCommand extends BaseCommand {
protected $signature = 'wn:resources
{file : Path to the file containing resources declarations}';
{file : Path to the file containing resources declarations}
{--path=app : where to store the model files.}
{--force= : override the existing files}
';
protected $description = 'Generates multiple resources from a file';
@ -19,37 +22,41 @@ class ResourcesCommand extends BaseCommand {
foreach ($content as $model => $i){
$i = $this->getResourceParams($model, $i);
$this->call('wn:resource', [
'name' => $i['name'],
'fields' => $i['fields'],
'--has-many' => $i['hasMany'],
'--has-one' => $i['hasOne'],
'--belongs-to' => $i['belongsTo'],
'--belongs-to-many' => $i['belongsToMany']
'--belongs-to-many' => $i['belongsToMany'],
'--path' => $this->option('path'),
'--force' => $this->option('force')
]);
}
$this->call('migrate');
// $this->call('migrate');
$this->pivotTables = array_map(
'unserialize',
'unserialize',
array_unique(array_map('serialize', $this->pivotTables))
);
foreach ($this->pivotTables as $tables) {
$this->call('wn:pivot-table', [
'model1' => $tables[0],
'model2' => $tables[1]
'model2' => $tables[1],
'--force' => $this->option('force')
]);
$this->call('wn:pivot-seeder', [
'model1' => $tables[0],
'model2' => $tables[1]
]);
// $this->call('wn:pivot-seeder', [
// 'model1' => $tables[0],
// 'model2' => $tables[1],
// '--force' => $this->option('force')
// ]);
}
$this->call('migrate');
// $this->call('migrate');
}
protected function getResourceParams($modelName, $i)
@ -68,12 +75,12 @@ class ResourcesCommand extends BaseCommand {
$relations = $this->getArgumentParser('relations')->parse($i['belongsTo']);
foreach ($relations as $relation){
$foreignName = '';
if(! $relation['model']){
$foreignName = snake_case($relation['name']) . '_id';
} else {
$names = array_reverse(explode("\\", $relation['model']));
$foreignName = snake_case($names[0]) . '_id';
$foreignName = snake_case($names[0]) . '_id';
}
$i['fields'][$foreignName] = [
@ -87,12 +94,12 @@ class ResourcesCommand extends BaseCommand {
$relations = $this->getArgumentParser('relations')->parse($i['belongsToMany']);
foreach ($relations as $relation){
$table = '';
if(! $relation['model']){
$table = snake_case($relation['name']);
} else {
$names = array_reverse(explode("\\", $relation['model']));
$table = snake_case($names[0]);
$table = snake_case($names[0]);
}
$tables = [ str_singular($table), $i['name'] ];
@ -120,7 +127,7 @@ class ResourcesCommand extends BaseCommand {
$string = "{$name};{$schema};{$rules};{$tags}";
if($field['factory']){
if(isset($field['factory']) && !empty($field['factory'])){
$string .= ';' . $field['factory'];
}

View File

@ -22,9 +22,7 @@ class RouteCommand extends BaseCommand {
])
->get();
$this->save($content, './app/Http/routes.php');
$this->info("{$resource} routes generated !");
$this->save($content, './app/Http/routes.php', "{$resource} routes", true);
}
protected function getController()
@ -35,5 +33,5 @@ class RouteCommand extends BaseCommand {
}
return $controller;
}
}

View File

@ -6,6 +6,7 @@ class SeederCommand extends BaseCommand {
protected $signature = 'wn:seeder
{model : full qualified name of the model.}
{--count=10 : number of elements to add in database.}
{--force= : override the existing files}
';
protected $description = 'Generates a seeder';
@ -25,9 +26,7 @@ class SeederCommand extends BaseCommand {
->get();
$this->save($content, $file);
$this->info("{$name} generated !");
$this->save($content, $file, $name);
}
protected function getSeederName($name)

View File

@ -16,8 +16,8 @@ class CommandsServiceProvider extends ServiceProvider
$this->registerResourcesCommand();
$this->registerPivotTableCommand();
$this->registerFactoryCommand();
$this->registerSeederCommand();
$this->registerPivotSeederCommand();
// $this->registerSeederCommand();
// $this->registerPivotSeederCommand();
// $this->registerTestCommand();
}

View File

@ -12,7 +12,7 @@ class {{name}}Table extends Migration
$table->increments('id');
{{schema}}
{{constraints}}
$table->timestamps();
{{additionals}}
});
}