diff --git a/README.md b/README.md index a50142e..5389e79 100644 --- a/README.md +++ b/README.md @@ -17,23 +17,34 @@ To do that, put this in your shell profile (~/.bash_profile, ~/.zshrc, ~/bashrc) - **make** - `make:controller` Create a new resource Controller class in a service - `make:feature ` Create a new Feature in a service + - `make:operation ` Create a new Operation in a service - `make:job ` Create a new Job in a domain - `make:service ` Create a new Service + - `make:model ` Create a new Model + - `make:request ` Create a new Request in a service + - `make:policy ` Create a new Policy - **list** - `list:features` List the features. - `list:services` List the services in this project. - **delete** - `delete:feature` Delete an existing Feature in a service + - `delete:operation` Delete an existing Operation in a service - `delete:job ` Delete an existing Job in a domain - `delete:service` Delete an existing Service + - `delete:model ` Delete an existing Model + - `delete:request ` Delete an existing Request in a service + - `delete:policy ` Delete an existing Policy ### Commands Usage #### Make - `make:controller []` - `make:feature []` -- `make:job ` +- `make:job [--queue]` - `make:service ` +- `make:model ` +- `make:request []` +- `make:policy ` #### List - `list:services` @@ -43,3 +54,6 @@ To do that, put this in your shell profile (~/.bash_profile, ~/.zshrc, ~/bashrc) - `delete:service ` - `delete:feature []` - `delete:job ` +- `delete:model ` +- `delete:request []` +- `delete:policy ` diff --git a/config/lucid.php b/config/lucid.php new file mode 100644 index 0000000..fbbd85a --- /dev/null +++ b/config/lucid.php @@ -0,0 +1,15 @@ + null, +]; \ No newline at end of file diff --git a/lucid b/lucid index ca50761..37de904 100755 --- a/lucid +++ b/lucid @@ -19,6 +19,16 @@ $commands = [ new Lucid\Console\Commands\ControllerMakeCommand(), new Lucid\Console\Commands\ServicesListCommand(), new Lucid\Console\Commands\FeaturesListCommand(), + + new \Lucid\Console\Commands\ModelMakeCommand(), + new \Lucid\Console\Commands\ModelDeleteCommand(), + new \Lucid\Console\Commands\RequestMakeCommand(), + new \Lucid\Console\Commands\RequestDeleteCommand(), + new \Lucid\Console\Commands\PolicyMakeCommand(), + new \Lucid\Console\Commands\PolicyDeleteCommand(), + + new \Lucid\Console\Commands\OperationMakeCommand(), + new \Lucid\Console\Commands\OperationDeleteCommand(), ]; $app = new Symfony\Component\Console\Application('Lucid Console', '0.5.0'); diff --git a/src/Commands/JobMakeCommand.php b/src/Commands/JobMakeCommand.php index 983e1de..2b45972 100644 --- a/src/Commands/JobMakeCommand.php +++ b/src/Commands/JobMakeCommand.php @@ -11,13 +11,14 @@ namespace Lucid\Console\Commands; -use Lucid\Console\Str; -use Lucid\Console\Finder; use Lucid\Console\Command; use Lucid\Console\Filesystem; +use Lucid\Console\Finder; use Lucid\Console\Generators\JobGenerator; -use Symfony\Component\Console\Input\InputArgument; +use Lucid\Console\Str; use Symfony\Component\Console\Command\Command as SymfonyCommand; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; /** * @author Abed Halawi @@ -33,7 +34,7 @@ class JobMakeCommand extends SymfonyCommand * * @var string */ - protected $name = 'make:job'; + protected $name = 'make:job {--Q|queue}'; /** * The console command description. @@ -60,9 +61,9 @@ public function fire() $domain = studly_case($this->argument('domain')); $title = $this->parseName($this->argument('job')); - + $isQueueable = $this->option('queue'); try { - $job = $generator->generate($title, $domain); + $job = $generator->generate($title, $domain, $isQueueable); $this->info( 'Job class '.$title.' created successfully.'. @@ -83,6 +84,13 @@ public function getArguments() ]; } + public function getOptions() + { + return [ + ['queue', 'Q', InputOption::VALUE_NONE, 'Whether a job is queueable or not.'], + ]; + } + /** * Get the stub file for the generator. * diff --git a/src/Commands/ModelDeleteCommand.php b/src/Commands/ModelDeleteCommand.php new file mode 100644 index 0000000..c484b55 --- /dev/null +++ b/src/Commands/ModelDeleteCommand.php @@ -0,0 +1,101 @@ + + * + * @package Lucid\Console\Commands + */ +class ModelDeleteCommand extends SymfonyCommand +{ + use Finder; + use Command; + use Filesystem; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'delete:model'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Delete an existing Eloquent Model.'; + + /** + * The type of class being generated + * @var string + */ + protected $type = 'Model'; + + /** + * Execute the console command. + * + * @return bool|null + */ + public function fire() + { + try { + $model = $this->parseModelName($this->argument('model')); + + if ( ! $this->exists($path = $this->findModelPath($model))) { + $this->error('Model class ' . $model . ' cannot be found.'); + } else { + $this->delete($path); + + $this->info('Model class ' . $model . ' deleted successfully.'); + } + } catch (Exception $e) { + $this->error($e->getMessage()); + } + } + + /** + * Get the console command arguments. + * + * @return array + */ + public function getArguments() + { + return [ + ['model', InputArgument::REQUIRED, 'The Model\'s name.'] + ]; + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + public function getStub() + { + return __DIR__ . '/../Generators/stubs/model.stub'; + } + + /** + * Parse the model name. + * + * @param string $name + * @return string + */ + public function parseModelName($name) + { + return Str::model($name); + } +} \ No newline at end of file diff --git a/src/Commands/ModelMakeCommand.php b/src/Commands/ModelMakeCommand.php new file mode 100644 index 0000000..1667a34 --- /dev/null +++ b/src/Commands/ModelMakeCommand.php @@ -0,0 +1,92 @@ + + * + * @package Lucid\Console\Commands + */ +class ModelMakeCommand extends SymfonyCommand +{ + use Finder; + use Command; + use Filesystem; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'make:model'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Create a new Eloquent Model.'; + + /** + * The type of class being generated + * @var string + */ + protected $type = 'Model'; + + /** + * Execute the console command. + * + * @return bool|null + */ + public function fire() + { + $generator = new ModelGenerator(); + + $name = $this->argument('model'); + + try { + $model = $generator->generate($name); + + $this->info('Model class created successfully.' . + "\n" . + "\n" . + 'Find it at ' . $model->relativePath . '' . "\n" + ); + } catch (Exception $e) { + $this->error($e->getMessage()); + } + } + + /** + * Get the console command arguments. + * + * @return array + */ + public function getArguments() + { + return [ + ['model', InputArgument::REQUIRED, 'The Model\'s name.'] + ]; + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + public function getStub() + { + return __DIR__ . '/../Generators/stubs/model.stub'; + } +} \ No newline at end of file diff --git a/src/Commands/OperationDeleteCommand.php b/src/Commands/OperationDeleteCommand.php new file mode 100644 index 0000000..ac44680 --- /dev/null +++ b/src/Commands/OperationDeleteCommand.php @@ -0,0 +1,110 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Lucid\Console\Commands; + +use Lucid\Console\Str; +use Lucid\Console\Finder; +use Lucid\Console\Command; +use Lucid\Console\Filesystem; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Command\Command as SymfonyCommand; + +/** + * @author Ali Issa + */ +class OperationDeleteCommand extends SymfonyCommand +{ + use Finder; + use Command; + use Filesystem; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'delete:operation'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Delete an existing Operation in a service'; + + /** + * The type of class being deleted. + * + * @var string + */ + protected $type = 'Operation'; + + /** + * Execute the console command. + * + * @return bool|null + */ + public function fire() + { + try { + $service = Str::service($this->argument('service')); + $title = $this->parseName($this->argument('operation')); + + if (!$this->exists($operation = $this->findOperationPath($service, $title))) { + $this->error('Operation class '.$title.' cannot be found.'); + } else { + $this->delete($operation); + + $this->info('Operation class '.$title.' deleted successfully.'); + } + } catch (Exception $e) { + $this->error($e->getMessage()); + } + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['operation', InputArgument::REQUIRED, 'The operation\'s name.'], + ['service', InputArgument::OPTIONAL, 'The service from which the operation should be deleted.'], + ]; + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + protected function getStub() + { + return __DIR__.'/../Generators/stubs/operation.stub'; + } + + /** + * Parse the operation name. + * remove the Operation.php suffix if found + * we're adding it ourselves. + * + * @param string $name + * + * @return string + */ + protected function parseName($name) + { + return Str::operation($name); + } +} diff --git a/src/Commands/OperationMakeCommand.php b/src/Commands/OperationMakeCommand.php new file mode 100644 index 0000000..463a98f --- /dev/null +++ b/src/Commands/OperationMakeCommand.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Lucid\Console\Commands; + +use Lucid\Console\Command; +use Lucid\Console\Filesystem; +use Lucid\Console\Finder; +use Lucid\Console\Generators\OperationGenerator; +use Lucid\Console\Str; +use Symfony\Component\Console\Command\Command as SymfonyCommand; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputOption; + +/** + * @author Ali Issa + */ +class OperationMakeCommand extends SymfonyCommand +{ + use Finder; + use Command; + use Filesystem; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'make:operation {--Q|queue}'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Create a new Operation in a domain'; + + /** + * The type of class being generated. + * + * @var string + */ + protected $type = 'Operation'; + + /** + * Execute the console command. + * + * @return bool|null + */ + public function fire() + { + $generator = new OperationGenerator(); + + $service = studly_case($this->argument('service')); + $title = $this->parseName($this->argument('operation')); + $isQueueable = $this->option('queue'); + try { + $operation = $generator->generate($title, $service, $isQueueable); + + $this->info( + 'Operation class '.$title.' created successfully.'. + "\n". + "\n". + 'Find it at '.$operation->relativePath.''."\n" + ); + } catch (Exception $e) { + $this->error($e->getMessage()); + } + } + + public function getArguments() + { + return [ + ['operation', InputArgument::REQUIRED, 'The operation\'s name.'], + ['service', InputArgument::OPTIONAL, 'The service in which the operation should be implemented.'], + ]; + } + + public function getOptions() + { + return [ + ['queue', 'Q', InputOption::VALUE_NONE, 'Whether a operation is queueable or not.'], + ]; + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + public function getStub() + { + return __DIR__.'/../Generators/stubs/operation.stub'; + } + + /** + * Parse the operation name. + * remove the Operation.php suffix if found + * we're adding it ourselves. + * + * @param string $name + * + * @return string + */ + protected function parseName($name) + { + return Str::operation($name); + } +} diff --git a/src/Commands/PolicyDeleteCommand.php b/src/Commands/PolicyDeleteCommand.php new file mode 100644 index 0000000..c10df9b --- /dev/null +++ b/src/Commands/PolicyDeleteCommand.php @@ -0,0 +1,101 @@ + + * + * @package Lucid\Console\Commands + */ +class PolicyDeleteCommand extends SymfonyCommand +{ + use Finder; + use Command; + use Filesystem; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'delete:policy'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Delete an existing Policy.'; + + /** + * The type of class being generated + * @var string + */ + protected $type = 'Policy'; + + /** + * Execute the console command. + * + * @return bool|null + */ + public function fire() + { + try { + $policy = $this->parsePolicyName($this->argument('policy')); + + if ( ! $this->exists($path = $this->findPolicyPath($policy))) { + $this->error('Policy class ' . $policy . ' cannot be found.'); + } else { + $this->delete($path); + + $this->info('Policy class ' . $policy . ' deleted successfully.'); + } + } catch (Exception $e) { + $this->error($e->getMessage()); + } + } + + /** + * Get the console command arguments. + * + * @return array + */ + public function getArguments() + { + return [ + ['policy', InputArgument::REQUIRED, 'The Policy\'s name.'] + ]; + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + public function getStub() + { + return __DIR__ . '/../Generators/stubs/policy.stub'; + } + + /** + * Parse the model name. + * + * @param string $name + * @return string + */ + public function parsePolicyName($name) + { + return Str::policy($name); + } +} \ No newline at end of file diff --git a/src/Commands/PolicyMakeCommand.php b/src/Commands/PolicyMakeCommand.php new file mode 100644 index 0000000..7dd26b3 --- /dev/null +++ b/src/Commands/PolicyMakeCommand.php @@ -0,0 +1,92 @@ + + * + * @package Lucid\Console\Commands + */ +class PolicyMakeCommand extends SymfonyCommand +{ + use Finder; + use Command; + use Filesystem; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'make:policy'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Create a Policy.'; + + /** + * The type of class being generated + * @var string + */ + protected $type = 'Policy'; + + /** + * Execute the console command. + * + * @return bool|null + */ + public function fire() + { + $generator = new PolicyGenerator(); + + $name = $this->argument('policy'); + + try { + $policy = $generator->generate($name); + + $this->info('Policy class created successfully.' . + "\n" . + "\n" . + 'Find it at ' . $policy->relativePath . '' . "\n" + ); + } catch (Exception $e) { + $this->error($e->getMessage()); + } + } + + /** + * Get the console command arguments. + * + * @return array + */ + public function getArguments() + { + return [ + ['policy', InputArgument::REQUIRED, 'The Policy\'s name.'] + ]; + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + public function getStub() + { + return __DIR__ . '/../Generators/stubs/policy.stub'; + } +} \ No newline at end of file diff --git a/src/Commands/RequestDeleteCommand.php b/src/Commands/RequestDeleteCommand.php new file mode 100644 index 0000000..e0ebc0c --- /dev/null +++ b/src/Commands/RequestDeleteCommand.php @@ -0,0 +1,103 @@ + + * + * @package Lucid\Console\Commands + */ +class RequestDeleteCommand extends SymfonyCommand +{ + use Finder; + use Command; + use Filesystem; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'delete:request'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Delete an existing Request.'; + + /** + * The type of class being generated + * @var string + */ + protected $type = 'Request'; + + /** + * Execute the console command. + * + * @return bool|null + */ + public function fire() + { + try { + $request = $this->parseRequestName($this->argument('request')); + $service = Str::service($this->argument('service')); + + if ( ! $this->exists($path = $this->findRequestPath($service, $request))) { + $this->error('Request class ' . $request . ' cannot be found.'); + } else { + $this->delete($path); + + $this->info('Request class ' . $request . ' deleted successfully.'); + } + } catch (Exception $e) { + $this->error($e->getMessage()); + } + } + + /** + * Get the console command arguments. + * + * @return array + */ + public function getArguments() + { + return [ + ['request', InputArgument::REQUIRED, 'The Request\'s name.'], + ['service', InputArgument::REQUIRED, 'The Service\'s name.'], + ]; + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + public function getStub() + { + return __DIR__ . '/../Generators/stubs/request.stub'; + } + + /** + * Parse the model name. + * + * @param string $name + * @return string + */ + public function parseRequestName($name) + { + return Str::request($name); + } +} \ No newline at end of file diff --git a/src/Commands/RequestMakeCommand.php b/src/Commands/RequestMakeCommand.php new file mode 100644 index 0000000..f1a7316 --- /dev/null +++ b/src/Commands/RequestMakeCommand.php @@ -0,0 +1,94 @@ + + * + * @package Lucid\Console\Commands + */ +class RequestMakeCommand extends SymfonyCommand +{ + use Finder; + use Command; + use Filesystem; + + /** + * The console command name. + * + * @var string + */ + protected $name = 'make:request'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Create a Request in a specific service.'; + + /** + * The type of class being generated + * @var string + */ + protected $type = 'Request'; + + /** + * Execute the console command. + * + * @return bool|null + */ + public function fire() + { + $generator = new RequestGenerator(); + + $name = $this->argument('request'); + $service = $this->argument('service'); + + try { + $request = $generator->generate($name, $service); + + $this->info('Request class created successfully.' . + "\n" . + "\n" . + 'Find it at ' . $request->relativePath . '' . "\n" + ); + } catch (Exception $e) { + $this->error($e->getMessage()); + } + } + + /** + * Get the console command arguments. + * + * @return array + */ + public function getArguments() + { + return [ + ['request', InputArgument::REQUIRED, 'The Request\'s name.'], + ['service', InputArgument::REQUIRED, 'The Service\'s name.'], + ]; + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + public function getStub() + { + return __DIR__ . '/../Generators/stubs/request.stub'; + } +} \ No newline at end of file diff --git a/src/Components/Model.php b/src/Components/Model.php new file mode 100644 index 0000000..1cd7966 --- /dev/null +++ b/src/Components/Model.php @@ -0,0 +1,26 @@ + + * + * @package Lucid\Console\Components + */ +class Model extends Component +{ + public function __construct($title, $namespace, $file, $path, $relativePath, $content) + { + $this->setAttributes([ + 'model' => $title, + 'namespace' => $namespace, + 'file' => $file, + 'path' => $path, + 'relativePath' => $relativePath, + 'content' => $content, + ]); + } +} \ No newline at end of file diff --git a/src/Components/Operation.php b/src/Components/Operation.php new file mode 100644 index 0000000..f2515f6 --- /dev/null +++ b/src/Components/Operation.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Lucid\Console\Components; + +/** + * @author Ali Issa + */ +class Operation extends Component +{ + public function __construct($title, $file, $realPath, $relativePath, Service $service = null, $content = '') + { + $className = str_replace(' ', '', $title).'Operation'; + + $this->setAttributes([ + 'title' => $title, + 'className' => $className, + 'service' => $service, + 'file' => $file, + 'realPath' => $realPath, + 'relativePath' => $relativePath, + 'content' => $content, + ]); + } +} diff --git a/src/Components/Policy.php b/src/Components/Policy.php new file mode 100644 index 0000000..3f71c91 --- /dev/null +++ b/src/Components/Policy.php @@ -0,0 +1,26 @@ + + * + * @package Lucid\Console\Components + */ +class Policy extends Component +{ + public function __construct($title, $namespace, $file, $path, $relativePath, $content) + { + $this->setAttributes([ + 'policy' => $title, + 'namespace' => $namespace, + 'file' => $file, + 'path' => $path, + 'relativePath' => $relativePath, + 'content' => $content, + ]); + } +} \ No newline at end of file diff --git a/src/Components/Request.php b/src/Components/Request.php new file mode 100644 index 0000000..3110486 --- /dev/null +++ b/src/Components/Request.php @@ -0,0 +1,28 @@ + + * + * @package Lucid\Console\Components + */ +class Request extends Component +{ + public function __construct($title, $service, $namespace, $file, $path, $relativePath, $content) + { + $this->setAttributes([ + 'request' => $title, + 'service' => $service, + 'namespace' => $namespace, + 'file' => $file, + 'path' => $path, + 'relativePath' => $relativePath, + 'content' => $content, + ]); + } +} \ No newline at end of file diff --git a/src/Filesystem.php b/src/Filesystem.php index 8c881b8..f547002 100644 --- a/src/Filesystem.php +++ b/src/Filesystem.php @@ -41,6 +41,8 @@ public function exists($path) */ public function createFile($path, $contents = '', $lock = false) { + $this->createDirectory(dirname($path)); + return file_put_contents($path, $contents, $lock ? LOCK_EX : 0); } diff --git a/src/Finder.php b/src/Finder.php index b98c165..5a4171e 100644 --- a/src/Finder.php +++ b/src/Finder.php @@ -274,6 +274,70 @@ public function findFeatureTestNamespace($service) return $this->findServiceNamespace($service).'\\Tests\\Features'; } + /** + * Find the operations root path in the given service. + * + * @param string $service + * + * @return string + */ + public function findOperationsRootPath($service) + { + return $this->findServicePath($service).'/Operations'; + } + + /** + * Find the file path for the given operation. + * + * @param string $service + * @param string $operation + * + * @return string + */ + public function findOperationPath($service, $operation) + { + return $this->findOperationsRootPath($service)."/$operation.php"; + } + + /** + * Find the test file path for the given operation. + * + * @param string $service + * @param string $operation + * + * @return string + */ + public function findOperationTestPath($service, $test) + { + $root = ($service) ? $this->findServicePath($service).'/Tests' : base_path().'/tests'; + + return "$root/Operations/$test.php"; + } + + /** + * Find the namespace for operations in the given service. + * + * @param string $service + * + * @return string + */ + public function findOperationNamespace($service) + { + return $this->findServiceNamespace($service).'\\Operations'; + } + + /** + * Find the namespace for operations tests in the given service. + * + * @param string $service + * + * @return string + */ + public function findOperationTestNamespace($service) + { + return $this->findServiceNamespace($service).'\\Tests\\Operations'; + } + /** * Find the root path of domains. * @@ -589,7 +653,7 @@ public function findJob($name) $files = $finder->name($fileName)->in($this->findDomainsRootPath())->files(); foreach ($files as $file) { $path = $file->getRealPath(); - $domainName = strstr($file->getRelativePath(), '/', true); + $domainName = strstr($file->getRelativePath(), DIRECTORY_SEPARATOR, true); $domain = $this->findDomain($domainName); $content = file_get_contents($path); @@ -653,6 +717,97 @@ public function listFeatures($serviceName = '') return $features; } + /** + * Get the path to the passed model. + * + * @param string $model + * + * @return string + */ + public function findModelPath($model) + { + return $this->getSourceDirectoryName().'/Data/'.$model.'.php'; + } + + /** + * Get the path to the policies directory. + * + * @return string + */ + public function findPoliciesPath() + { + return $this->getSourceDirectoryName().'/Policies'; + } + + /** + * Get the path to the passed policy. + * + * @param string $policy + * + * @return string + */ + public function findPolicyPath($policy) + { + return $this->findPoliciesPath().'/'.$policy.'.php'; + } + + /** + * Get the path to the request directory of a specific service. + * + * @param string $service + * + * @return string + */ + public function findRequestsPath($service) + { + return $this->findServicePath($service).'/Http/Requests'; + } + + /** + * Get the path to a specific request. + * + * @param string $service + * @param string $request + * + * @return string + */ + public function findRequestPath($service, $request) + { + return $this->findRequestsPath($service).'/'.$request.'.php'; + } + + /** + * Get the namespace for the Models. + * + * @return string + */ + public function findModelNamespace() + { + return $this->findRootNamespace().'\\Data'; + } + + /** + * Get the namespace for Policies. + * + * @return mixed + */ + public function findPolicyNamespace() + { + return $this->findRootNamespace().'\\Policies'; + } + + /** + * Get the requests namespace for the service passed in. + * + * @param string $service + * + * @return string + */ + public function findRequestsNamespace($service) + { + return $this->findServiceNamespace($service).'\\Http\\Requests'; + } + /** * Get the relative version of the given real path. * diff --git a/src/Generators/JobGenerator.php b/src/Generators/JobGenerator.php index 93086ad..7541c8a 100644 --- a/src/Generators/JobGenerator.php +++ b/src/Generators/JobGenerator.php @@ -20,7 +20,7 @@ */ class JobGenerator extends Generator { - public function generate($job, $domain) + public function generate($job, $domain, $isQueueable = false) { $job = Str::job($job); $domain = Str::domain($domain); @@ -38,7 +38,7 @@ public function generate($job, $domain) // Create the job $namespace = $this->findDomainJobsNamespace($domain); - $content = file_get_contents($this->getStub()); + $content = file_get_contents($this->getStub($isQueueable)); $content = str_replace( ['{{job}}', '{{namespace}}', '{{foundation_namespace}}'], [$job, $namespace, $this->findFoundationNamespace()], @@ -101,9 +101,15 @@ private function createDomainDirectory($domain) * * @return string */ - public function getStub() + public function getStub($isQueueable = false) { - return __DIR__.'/stubs/job.stub'; + $stubName; + if ($isQueueable) { + $stubName = '/stubs/queueable-job.stub'; + } else { + $stubName = '/stubs/job.stub'; + } + return __DIR__.$stubName; } /** diff --git a/src/Generators/ModelGenerator.php b/src/Generators/ModelGenerator.php new file mode 100644 index 0000000..ab353c8 --- /dev/null +++ b/src/Generators/ModelGenerator.php @@ -0,0 +1,67 @@ + + * + * @package Lucid\Console\Generators + */ +class ModelGenerator extends Generator +{ + /** + * Generate the file. + * + * @param $name + * @return Model|bool + * @throws Exception + */ + public function generate($name) + { + $model = Str::model($name); + $path = $this->findModelPath($model); + + if ($this->exists($path)) { + throw new Exception('Model already exists'); + + return false; + } + + $namespace = $this->findModelNamespace(); + + $content = file_get_contents($this->getStub()); + $content = str_replace( + ['{{model}}', '{{namespace}}', '{{foundation_namespace}}'], + [$model, $namespace, $this->findFoundationNamespace()], + $content + ); + + $this->createFile($path, $content); + + return new Model( + $model, + $namespace, + basename($path), + $path, + $this->relativeFromReal($path), + $content + ); + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + public function getStub() + { + return __DIR__ . '/../Generators/stubs/model.stub'; + } +} \ No newline at end of file diff --git a/src/Generators/OperationGenerator.php b/src/Generators/OperationGenerator.php new file mode 100644 index 0000000..5a5fd93 --- /dev/null +++ b/src/Generators/OperationGenerator.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Lucid\Console\Generators; + +use Exception; +use Lucid\Console\Str; +use Lucid\Console\Components\Operation; + +/** + * @author Ali Issa + */ +class OperationGenerator extends Generator +{ + public function generate($operation, $service, $isQueueable = false, array $jobs = []) + { + $operation = Str::operation($operation); + $service = Str::service($service); + + $path = $this->findOperationPath($service, $operation); + + if ($this->exists($path)) { + throw new Exception('Operation already exists!'); + + return false; + } + + $namespace = $this->findOperationNamespace($service); + + $content = file_get_contents($this->getStub($isQueueable)); + + $useJobs = ''; // stores the `use` statements of the jobs + $runJobs = ''; // stores the `$this->run` statements of the jobs + + foreach ($jobs as $index => $job) { + $useJobs .= 'use '.$job['namespace'].'\\'.$job['className'].";\n"; + $runJobs .= "\t\t".'$this->run('.$job['className'].'::class);'; + + // only add carriage returns when it's not the last job + if ($index != count($jobs) - 1) { + $runJobs .= "\n\n"; + } + } + + $content = str_replace( + ['{{operation}}', '{{namespace}}', '{{foundation_namespace}}', '{{use_jobs}}', '{{run_jobs}}'], + [$operation, $namespace, $this->findFoundationNamespace(), $useJobs, $runJobs], + $content + ); + + $this->createFile($path, $content); + + // generate test file + $this->generateTestFile($operation, $service); + + return new Operation( + $operation, + basename($path), + $path, + $this->relativeFromReal($path), + ($service) ? $this->findService($service) : null, + $content + ); + } + + /** + * Generate the test file. + * + * @param string $operation + * @param string $service + */ + private function generateTestFile($operation, $service) + { + $content = file_get_contents($this->getTestStub()); + + $namespace = $this->findOperationTestNamespace($service); + $operationNamespace = $this->findOperationNamespace($service)."\\$operation"; + $testClass = $operation.'Test'; + + $content = str_replace( + ['{{namespace}}', '{{testclass}}', '{{operation}}', '{{operation_namespace}}'], + [$namespace, $testClass, mb_strtolower($operation), $operationNamespace], + $content + ); + + $path = $this->findOperationTestPath($service, $testClass); + + $this->createFile($path, $content); + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + protected function getStub($isQueueable = false) + { + $stubName; + if ($isQueueable) { + $stubName = '/stubs/queueable-operation.stub'; + } else { + $stubName = '/stubs/operation.stub'; + } + return __DIR__.$stubName; + } + + /** + * Get the test stub file for the generator. + * + * @return string + */ + private function getTestStub() + { + return __DIR__.'/stubs/operation-test.stub'; + } +} diff --git a/src/Generators/PolicyGenerator.php b/src/Generators/PolicyGenerator.php new file mode 100644 index 0000000..bec571b --- /dev/null +++ b/src/Generators/PolicyGenerator.php @@ -0,0 +1,78 @@ + + * + * @package Lucid\Console\Generators + */ +class PolicyGenerator extends Generator +{ + /** + * Generate the file. + * + * @param $name + * @return Policy|bool + * @throws Exception + */ + public function generate($name) + { + $policy = Str::policy($name); + $path = $this->findPolicyPath($policy); + + if ($this->exists($path)) { + throw new Exception('Policy already exists'); + + return false; + } + + $this->createPolicyDirectory(); + + $namespace = $this->findPolicyNamespace(); + + $content = file_get_contents($this->getStub()); + $content = str_replace( + ['{{policy}}', '{{namespace}}', '{{foundation_namespace}}'], + [$policy, $namespace, $this->findFoundationNamespace()], + $content + ); + + $this->createFile($path, $content); + + return new Policy( + $policy, + $namespace, + basename($path), + $path, + $this->relativeFromReal($path), + $content + ); + } + + /** + * Create Policies directory. + */ + public function createPolicyDirectory() + { + $this->createDirectory($this->findPoliciesPath()); + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + public function getStub() + { + return __DIR__ . '/../Generators/stubs/policy.stub'; + } +} \ No newline at end of file diff --git a/src/Generators/RequestGenerator.php b/src/Generators/RequestGenerator.php new file mode 100644 index 0000000..4d891e2 --- /dev/null +++ b/src/Generators/RequestGenerator.php @@ -0,0 +1,71 @@ + + * + * @package Lucid\Console\Generators + */ +class RequestGenerator extends Generator +{ + /** + * Generate the file. + * + * @param string $name + * @param string $service + * @return Request|bool + * @throws Exception + */ + public function generate($name, $service) + { + $request = Str::request($name); + $service = Str::service($service); + $path = $this->findRequestPath($service, $request); + + if ($this->exists($path)) { + throw new Exception('Request already exists'); + + return false; + } + + $namespace = $this->findRequestsNamespace($service); + + $content = file_get_contents($this->getStub()); + $content = str_replace( + ['{{request}}', '{{namespace}}', '{{foundation_namespace}}'], + [$request, $namespace, $this->findFoundationNamespace()], + $content + ); + + $this->createFile($path, $content); + + return new Request( + $request, + $service, + $namespace, + basename($path), + $path, + $this->relativeFromReal($path), + $content + ); + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + public function getStub() + { + return __DIR__ . '/../Generators/stubs/request.stub'; + } +} \ No newline at end of file diff --git a/src/Generators/stubs/job.stub b/src/Generators/stubs/job.stub index 39bc0ad..9869db2 100644 --- a/src/Generators/stubs/job.stub +++ b/src/Generators/stubs/job.stub @@ -5,13 +5,23 @@ use {{foundation_namespace}}\Job; class {{job}} extends Job { + /** + * Create a new job instance. + * + * @return void + */ public function __construct() { - + // } + /** + * Execute the job. + * + * @return void + */ public function handle() { - + // } } diff --git a/src/Generators/stubs/model.stub b/src/Generators/stubs/model.stub new file mode 100644 index 0000000..2f7e7de --- /dev/null +++ b/src/Generators/stubs/model.stub @@ -0,0 +1,10 @@ +markTestIncomplete(); + } +} diff --git a/src/Generators/stubs/operation.stub b/src/Generators/stubs/operation.stub new file mode 100644 index 0000000..8e801d8 --- /dev/null +++ b/src/Generators/stubs/operation.stub @@ -0,0 +1,13 @@ +app->routesAreCached()) { - require_once __DIR__.'/Http/routes.php'; + $configPath = __DIR__ . '/../config/lucid.php'; + $this->publishes([$configPath => $this->getConfigPath()], 'config'); + + $dashboardEnabled = $this->app['config']->get('lucid.dashboard'); + + if ($dashboardEnabled === null) { + $dashboardEnabled = $this->app['config']->get('app.debug'); + } + + if ($dashboardEnabled === true) { + if (!$this->app->routesAreCached() ) { + require_once __DIR__.'/Http/routes.php'; + } } $this->loadViewsFrom(__DIR__.'/../resources/views', 'lucid'); @@ -40,6 +51,19 @@ public function boot() */ public function register() { + $configPath = __DIR__ . '/../config/lucid.php'; + $this->mergeConfigFrom($configPath, 'lucid'); + $this->app->register(LogReaderServiceProvider::class); } + + /** + * Return path to config file. + * + * @return string + */ + private function getConfigPath() + { + return config_path('lucid.php'); + } } diff --git a/src/Str.php b/src/Str.php index ed5509b..3d7110f 100644 --- a/src/Str.php +++ b/src/Str.php @@ -66,6 +66,22 @@ public static function job($name) return studly_case(preg_replace('/Job(\.php)?$/', '', $name).'Job'); } + /** + * Get the given name formatted as an operation. + * + * i.e. "Create Post Operation", "CreatePostOperation.php", "createPost", + * and many other forms will be transformed to "CreatePostOperation" which is + * the standard operation class name. + * + * @param string $name + * + * @return string + */ + public static function operation($name) + { + return studly_case(preg_replace('/Operation(\.php)?$/', '', $name).'Operation'); + } + /** * Get the given name formatted as a domain. * @@ -103,4 +119,40 @@ public static function controller($name) { return studly_case(preg_replace('/Controller(\.php)?$/', '', $name).'Controller'); } + + /** + * Get the given name formatted as a model. + * + * Model names are just CamelCase + * + * @param string $name + * + * @return string + */ + public static function model($name) + { + return studly_case($name); + } + + /** + * Get the given name formatted as a policy. + * + * @param $name + * @return string + */ + public static function policy($name) + { + return studly_case(preg_replace('/Policy(\.php)?$/', '', $name) . 'Policy'); + } + + /** + * Get the given name formatted as a request. + * + * @param $name + * @return string + */ + public static function request($name) + { + return studly_case(preg_replace('/Request(\.php)?$/', '', $name) . 'Request'); + } }