Skip to content

Commit

Permalink
Merge pull request #7 from savannabits/0.x-dev
Browse files Browse the repository at this point in the history
Package Api Improvement: Collect Reusable generator modifications to a Concern
  • Loading branch information
coolsam726 authored Apr 6, 2024
2 parents f823a78 + 68b65f3 commit 9aa5426
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 33 deletions.
125 changes: 125 additions & 0 deletions src/Commands/FactoryMakeCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

namespace Savannabits\Modular\Commands;

use Illuminate\Console\GeneratorCommand;
use Illuminate\Support\Str;
use Savannabits\Modular\Support\Concerns\GeneratesModularFiles;
use Symfony\Component\Console\Input\InputOption;

class FactoryMakeCommand extends GeneratorCommand
{
use GeneratesModularFiles;

/**
* The console command name.
*
* @var string
*/
protected $name = 'modular:make-factory';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Create a new model factory class in a modular package';

/**
* The type of class being generated.
*
* @var string
*/
protected $type = 'Factory';

/**
* Get the stub file for the generator.
*
* @return string
*/
protected function getStub()
{
return $this->resolveStubPath('/stubs/factory.stub');
}

protected function buildClass($name): string
{
$factory = class_basename(Str::ucfirst(str_replace('Factory', '', $name)));

$namespaceModel = $this->option('model')
? $this->qualifyModel($this->option('model'))
: $this->qualifyModel($this->guessModelName($name));

$model = class_basename($namespaceModel);

$namespace = $this->getNamespace(
$this->getModule()->makeNamespace('Database\\Factories\\')
);

$replace = [
'{{ factoryNamespace }}' => $namespace,
'NamespacedDummyModel' => $namespaceModel,
'{{ namespacedModel }}' => $namespaceModel,
'{{namespacedModel}}' => $namespaceModel,
'DummyModel' => $model,
'{{ model }}' => $model,
'{{model}}' => $model,
'{{ factory }}' => $factory,
'{{factory}}' => $factory,
];

return str_replace(
array_keys($replace), array_values($replace), parent::buildClass($name)
);
}

/**
* Get the destination class path.
*
* @param string $name
* @return string
*/
protected function getPath($name)
{
$name = (string) Str::of($name)->replaceFirst($this->rootNamespace(), '')->finish('Factory');

return $this->getModule()->factoriesPath(str_replace('\\', '/', $name).'.php');
}

/**
* Guess the model name from the Factory name or return a default model name.
*
* @param string $name
* @return string
*/
protected function guessModelName($name)
{
if (str_ends_with($name, 'Factory')) {
$name = substr($name, 0, -7);
}

$modelName = $this->qualifyModel(Str::after($name, $this->rootNamespace()));

if (class_exists($modelName)) {
return $modelName;
}

if (is_dir(app_path('Models/'))) {
return $this->rootNamespace().'Models\Model';
}

return $this->rootNamespace().'Model';
}

/**
* Get the console command options.
*
* @return array
*/
protected function getOptions()
{
return [
['model', 'm', InputOption::VALUE_OPTIONAL, 'The name of the model'],
];
}
}
43 changes: 10 additions & 33 deletions src/Commands/ModelMakeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,25 @@

use Illuminate\Foundation\Console\ModelMakeCommand as BaseModelMakeCommand;
use Illuminate\Support\Str;
use Savannabits\Modular\Facades\Modular;
use Savannabits\Modular\Module;
use Savannabits\Modular\Support\Concerns\GeneratesModularFiles;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputArgument;

#[AsCommand(name: 'modular:make-model')]
class ModelMakeCommand extends BaseModelMakeCommand
{
use GeneratesModularFiles;

protected $name = 'modular:make-model';

protected $description = 'Create a new Eloquent model class in a modular package';

protected function getArguments(): array
{
return array_merge(parent::getArguments(), [
['module', InputArgument::REQUIRED, 'The name of the module in which this should be installed'],
]);
}

public function getModule(): Module
{
return Modular::module($this->argument('module'));
}

protected function getDefaultNamespace($rootNamespace): string
{
return $rootNamespace.'\\Models';
}

protected function rootNamespace(): string
{
return $this->getModule()->getRootNamespace();
}

protected function getPath($name): string
{
$name = Str::replaceFirst($this->rootNamespace(), '', $name);

return $this->getModule()->srcPath(str_replace('\\', '/', $name).'.php');
}

protected function createFactory(): void
{
$factory = Str::studly($this->argument('name'));

$this->call('make:factory', [
$this->call('modular:make-factory', [
'name' => "{$factory}Factory",
'module' => $this->getModule()->name(),
'--model' => $this->qualifyClass($this->getNameInput()),
]);
}
Expand Down Expand Up @@ -116,4 +88,9 @@ protected function createPolicy(): void
'--model' => $this->qualifyClass($this->getNameInput()),
]);
}

protected function getRelativeNamespace(): string
{
return 'Models';
}
}
6 changes: 6 additions & 0 deletions src/Modular.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,10 @@ public function module(string $name): Module
{
return new Module($name);
}

public function packagePath(string $path = ''): string
{
//return the base path of this package
return __DIR__.'/../'.($path ? DIRECTORY_SEPARATOR.trim($path, DIRECTORY_SEPARATOR) : '');
}
}
52 changes: 52 additions & 0 deletions src/Support/Concerns/GeneratesModularFiles.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Savannabits\Modular\Support\Concerns;

use Illuminate\Support\Str;
use Savannabits\Modular\Facades\Modular;
use Savannabits\Modular\Module;
use Symfony\Component\Console\Input\InputArgument;

trait GeneratesModularFiles
{
protected function getArguments(): array
{
return array_merge(parent::getArguments(), [
['module', InputArgument::REQUIRED, 'The name of the module in which this should be installed'],
]);
}

protected function resolveStubPath($stub): string
{
return file_exists($customPath = $this->laravel->basePath(trim($stub, '/')))
? $customPath
: Modular::packagePath(trim($stub, DIRECTORY_SEPARATOR));
}

public function getModule(): Module
{
return Modular::module($this->argument('module'));
}

protected function getDefaultNamespace($rootNamespace): string
{
return trim($rootNamespace, '\\').'\\'.trim(Str::replace(DIRECTORY_SEPARATOR, '\\', $this->getRelativeNamespace()), '\\');
}

protected function getRelativeNamespace(): string
{
return '';
}

protected function rootNamespace(): string
{
return $this->getModule()->getRootNamespace();
}

protected function getPath($name): string
{
$name = Str::replaceFirst($this->rootNamespace(), '', $name);

return $this->getModule()->srcPath(str_replace('\\', '/', $name).'.php');
}
}

0 comments on commit 9aa5426

Please sign in to comment.