diff --git a/src/Commands/InitCommand.php b/src/Commands/InitCommand.php index 0275ff9..2185678 100644 --- a/src/Commands/InitCommand.php +++ b/src/Commands/InitCommand.php @@ -14,10 +14,12 @@ use RonasIT\ProjectInitializator\Enums\RoleEnum; use RonasIT\ProjectInitializator\Extensions\ConfigWriter\ArrayFile; use Winter\LaravelConfigWriter\EnvFile; +use RonasIT\ProjectInitializator\Generators\ReadmeGenerator; class InitCommand extends Command implements Isolatable { - public const string TEMPLATES_PATH = 'vendor/ronasit/laravel-project-initializator/resources/md/readme'; + protected $signature = 'init {application-name : The application name }'; + protected $description = 'Initialize required project parameters to run DEV environment'; public const array RESOURCES_ITEMS = [ 'issue_tracker' => 'Issue Tracker', @@ -43,24 +45,12 @@ class InitCommand extends Command implements Isolatable 'nova', ]; - protected $signature = 'init {application-name : The application name }'; - - protected $description = 'Initialize required project parameters to run DEV environment'; - - protected string $codeOwnerEmail; - protected array $resources = []; protected array $adminCredentials = []; - protected AuthTypeEnum $authType; - - protected string $appUrl; - protected array $emptyValuesList = []; - protected string $readmeContent = ''; - protected array $shellCommands = [ 'composer require laravel/ui', 'composer require ronasit/laravel-helpers', @@ -75,63 +65,43 @@ class InitCommand extends Command implements Isolatable ]; protected bool $shouldUninstallPackage = false; + protected bool $shouldGenerateReadme; protected string $appName; + protected string $kebabName; + protected string $appUrl; + protected AppTypeEnum $appType; + protected AuthTypeEnum $authType; + protected string $codeOwnerEmail; - protected string $dbConnection = 'pgsql'; - protected string $dbHost = 'pgsql'; - protected string $dbPort = '5432'; - protected string $dbName = 'postgres'; - protected string $dbUserName = 'postgres'; + protected string $envFile; + protected array $envConfig = [ + 'dbConnection' => 'pgsql', + 'dbHost' => 'pgsql', + 'dbPort' => '5432', + 'dbName' => 'postgres', + 'dbUserName' => 'postgres', + ]; - protected AppTypeEnum $appType; + public function __construct( + protected ReadmeGenerator $readmeGenerator + ) { + parent::__construct(); + } public function handle(): void { $this->prepareAppName(); - $kebabName = Str::kebab($this->appName); - $this->codeOwnerEmail = $this->validateInput( method: fn () => $this->ask('Please specify a Code Owner/Team Lead\'s email'), field: 'email of code owner / team lead', rules: 'required|email', ); - $this->appUrl = $this->ask('Please enter an application URL', "https://api.dev.{$kebabName}.com"); - - $envFile = (file_exists('.env')) ? '.env' : '.env.example'; - - $envConfig = [ - 'APP_NAME' => $this->appName, - 'DB_CONNECTION' => $this->dbConnection, - 'DB_HOST' => $this->dbHost, - 'DB_PORT' => $this->dbPort, - 'DB_DATABASE' => $this->dbName, - 'DB_USERNAME' => $this->dbUserName, - 'DB_PASSWORD' => '', - ]; - - $this->updateEnvFile($envFile, $envConfig); + $this->appUrl = $this->ask('Please enter an application URL', "https://api.dev.{$this->kebabName}.com"); - if (!file_exists('.env.development')) { - copy('.env.example', '.env.development'); - } - - $this->updateEnvFile('.env.development', [ - 'APP_NAME' => $this->appName, - 'APP_URL' => $this->appUrl, - 'APP_MAINTENANCE_DRIVER' => 'cache', - 'CACHE_STORE' => 'redis', - 'QUEUE_CONNECTION' => 'redis', - 'SESSION_DRIVER' => 'redis', - 'DB_CONNECTION' => $this->dbConnection, - 'DB_HOST' => '', - 'DB_PORT' => '', - 'DB_DATABASE' => '', - 'DB_USERNAME' => '', - 'DB_PASSWORD' => '', - ]); + $this->updateEnvFile(); $this->info('Project initialized successfully!'); @@ -149,85 +119,27 @@ public function handle(): void default: AuthTypeEnum::None->value, )); - if ($this->authType === AuthTypeEnum::Clerk) { - $this->enableClerk(); - - $data = [ - 'AUTH_GUARD' => 'clerk', - 'CLERK_ALLOWED_ISSUER' => '', - 'CLERK_SECRET_KEY' => '', - 'CLERK_SIGNER_KEY_PATH' => '', - ]; - - if ($this->appType !== AppTypeEnum::Mobile) { - $data['CLERK_ALLOWED_ORIGINS'] = ''; - } - - $this->updateEnvFile('.env.development', $data); - $this->updateEnvFile($envFile, $data); - - if ($envFile !== '.env.example') { - $this->updateEnvFile('.env.example', $data); - } - } + $this->configureClerk(); if ($this->confirm('Do you want to generate an admin user?', true)) { if ($this->authType === AuthTypeEnum::Clerk) { $this->publishAdminsTableMigration(); } - $this->createAdminUser($kebabName); + $this->createAdminUser(); } - if ($shouldGenerateReadme = $this->confirm('Do you want to generate a README file?', true)) { - $this->fillReadme(); - - if ($this->confirm('Do you need a `Resources & Contacts` part?', true)) { - $this->fillResourcesAndContacts(); - $this->fillResources(); - $this->fillContacts(); - } - - if ($this->confirm('Do you need a `Prerequisites` part?', true)) { - $this->fillPrerequisites(); - } - - if ($this->confirm('Do you need a `Getting Started` part?', true)) { - $this->fillGettingStarted(); - } - - if ($this->confirm('Do you need an `Environments` part?', true)) { - $this->fillEnvironments(); - } - - if ($this->confirm('Do you need a `Credentials and Access` part?', true)) { - $this->fillCredentialsAndAccess($kebabName); - - if ($this->authType === AuthTypeEnum::Clerk) { - $this->fillClerkAuthType(); - } - } - - $this->saveReadme(); - - $this->info('README generated successfully!'); - - if ($this->emptyValuesList) { - $this->warn('Don`t forget to fill the following empty values:'); - - foreach ($this->emptyValuesList as $value) { - $this->warn("- {$value}"); - } - } + if ($this->shouldGenerateReadme = $this->confirm('Do you want to generate a README file?', true)) { + $this->generateReadme(); } if ($this->confirm('Would you use Renovate dependabot?', true)) { $this->saveRenovateJSON(); - if ($shouldGenerateReadme) { - $this->fillRenovate(); + if ($this->shouldGenerateReadme) { + $this->readmeGenerator->fillRenovate(); - $this->saveReadme(); + $this->readmeGenerator->save(); } } @@ -266,64 +178,137 @@ public function handle(): void $this->runMigrations(); } - protected function setupComposerHooks(): void + protected function validateInput(callable $method, string $field, string|array $rules): string { - $path = base_path('composer.json'); + $value = $method(); - $content = file_get_contents($path); + $validator = Validator::make([$field => $value], [$field => $rules]); - $data = json_decode($content, true); + if ($validator->fails()) { + $this->warn($validator->errors()->first()); - $this->addArrayItemIfMissing($data, 'extra.hooks.config.stop-on-failure', 'pre-commit'); - $this->addArrayItemIfMissing($data, 'extra.hooks.pre-commit', 'docker compose up -d php && docker compose exec -T nginx vendor/bin/pint --repair'); - $this->addArrayItemIfMissing($data, 'scripts.post-install-cmd', '[ $COMPOSER_DEV_MODE -eq 0 ] || cghooks add --ignore-lock'); - $this->addArrayItemIfMissing($data, 'scripts.post-update-cmd', 'cghooks update'); + $value = $this->validateInput($method, $field, $rules); + } - $resultData = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"; + return $value; + } - file_put_contents($path, $resultData); + protected function prepareAppName(): void + { + $this->appName = $this->argument('application-name'); + + $pascalCaseAppName = ucfirst(Str::camel($this->appName)); + + if ($this->appName !== $pascalCaseAppName && $this->confirm("The application name is not in PascalCase, would you like to use {$pascalCaseAppName}", true)) { + $this->appName = $pascalCaseAppName; + } + + $this->kebabName = Str::kebab($this->appName); } - protected function addArrayItemIfMissing(array &$data, string $path, string $value): void + protected function updateEnvFile(): void { - $current = Arr::get($data, $path, []); + $this->envFile = (file_exists('.env')) ? '.env' : '.env.example'; - if (!in_array($value, $current)) { - $current[] = $value; + $envConfig = [ + 'APP_NAME' => $this->appName, + 'DB_CONNECTION' => $this->envConfig['dbConnection'], + 'DB_HOST' => $this->envConfig['dbHost'], + 'DB_PORT' => $this->envConfig['dbPort'], + 'DB_DATABASE' => $this->envConfig['dbName'], + 'DB_USERNAME' => $this->envConfig['dbUserName'], + 'DB_PASSWORD' => '', + ]; - Arr::set($data, $path, $current); + $this->writeEnvFile($this->envFile, $envConfig); + + if (!file_exists('.env.development')) { + copy('.env.example', '.env.development'); } + + $this->writeEnvFile('.env.development', [ + 'APP_NAME' => $this->appName, + 'APP_URL' => $this->appUrl, + 'APP_MAINTENANCE_DRIVER' => 'cache', + 'CACHE_STORE' => 'redis', + 'QUEUE_CONNECTION' => 'redis', + 'SESSION_DRIVER' => 'redis', + 'DB_CONNECTION' => $this->envConfig['dbConnection'], + 'DB_HOST' => '', + 'DB_PORT' => '', + 'DB_DATABASE' => '', + 'DB_USERNAME' => '', + 'DB_PASSWORD' => '', + ]); } - protected function setAutoDocContactEmail(string $email): void + protected function configureClerk(): void { - $config = ArrayFile::open(base_path('config/auto-doc.php')); + if ($this->authType === AuthTypeEnum::Clerk) { + $this->enableClerk(); - $config->set('info.contact.email', $email); + $data = [ + 'AUTH_GUARD' => 'clerk', + 'CLERK_ALLOWED_ISSUER' => '', + 'CLERK_SECRET_KEY' => '', + 'CLERK_SIGNER_KEY_PATH' => '', + ]; - $config->write(); + if ($this->appType !== AppTypeEnum::Mobile) { + $data['CLERK_ALLOWED_ORIGINS'] = ''; + } + + $this->writeEnvFile('.env.development', $data); + $this->writeEnvFile($this->envFile, $data); + + if ($this->envFile !== '.env.example') { + $this->writeEnvFile('.env.example', $data); + } + } } - protected function runMigrations(): void + protected function writeEnvFile(string $fileName, array $data): void { - config([ - 'database.default' => $this->dbConnection, - 'database.connections.pgsql' => [ - 'driver' => $this->dbConnection, - 'host' => $this->dbHost, - 'port' => $this->dbPort, - 'database' => $this->dbName, - 'username' => $this->dbUserName, - 'password' => '', - ], - ]); + $env = EnvFile::open($fileName); - shell_exec('php artisan migrate --ansi'); + // TODO: After updating wintercms/laravel-config-writer, remove the key comparison check and keep only $env->addEmptyLine(); + $envKeys = array_column($env->getAst(), 'match'); + $dataKeys = array_keys($data); + + $hasMissingKeys = count(array_intersect($dataKeys, $envKeys)) !== count($dataKeys); + + if ($hasMissingKeys) { + $env->addEmptyLine(); + } + + $env->set($data); + + $env->write(); + } + + protected function enableClerk(): void + { + array_push( + $this->shellCommands, + 'composer require ronasit/laravel-clerk', + 'php artisan laravel-clerk:install', + ); + + $this->publishMigration( + view: view('initializator::users_add_clerk_id_field'), + migrationName: 'users_add_clerk_id_field', + ); + + $this->publishClass( + template: view('initializator::clerk_user_repository'), + fileName: 'ClerkUserRepository', + filePath: 'app/Support/Clerk', + ); } - protected function createAdminUser(string $kebabName, string $serviceKey = '', string $serviceName = ''): array + protected function createAdminUser(string $serviceKey = '', string $serviceName = ''): array { - $adminEmail = when(empty($serviceKey), "admin@{$kebabName}.com", "admin.{$serviceKey}@{$kebabName}.com"); + $adminEmail = when(empty($serviceKey), "admin@{$this->kebabName}.com", "admin.{$serviceKey}@{$this->kebabName}.com"); $defaultPassword = substr(md5(uniqid()), 0, 8); $serviceLabel = when(!empty($serviceName), " for {$serviceName}"); @@ -347,27 +332,74 @@ protected function createAdminUser(string $kebabName, string $serviceKey = '', s return $adminCredentials; } - protected function fillReadme(): void + protected function publishMigration(View $view, string $migrationName): void { - $file = $this->loadReadmePart('README.md'); + $time = Carbon::now()->format('Y_m_d_His'); + + $migrationName = "{$time}_{$migrationName}"; + + $this->publishClass($view, $migrationName, 'database/migrations'); + } + + protected function publishClass(View $template, string $fileName, string $filePath): void + { + $fileName = "{$fileName}.php"; - $this->setReadmeValue($file, 'project_name', $this->appName); + if (!is_dir($filePath)) { + mkdir($filePath, 0777, true); + } - $this->setReadmeValue($file, 'type', $this->appType->value); + $data = $template->render(); - $this->readmeContent = $file; + file_put_contents("{$filePath}/{$fileName}", "loadReadmePart('RESOURCES_AND_CONTACTS.md'); + $this->readmeGenerator->generate($this->appName, $this->appType->value); + + if ($this->confirm('Do you need a `Resources & Contacts` part?', true)) { + $this->readmeGenerator->fillResourcesAndContacts(); + $this->fillResources(); + $this->fillContacts(); + } + + if ($this->confirm('Do you need a `Prerequisites` part?', true)) { + $this->readmeGenerator->fillPrerequisites(); + } - $this->updateReadmeFile($filePart); + if ($this->confirm('Do you need a `Getting Started` part?', true)) { + $this->fillGettingStarted(); + } + + if ($this->confirm('Do you need an `Environments` part?', true)) { + $this->readmeGenerator->fillEnvironments($this->appUrl); + } + + if ($this->confirm('Do you need a `Credentials and Access` part?', true)) { + $this->fillCredentialsAndAccess(); + + if ($this->authType === AuthTypeEnum::Clerk) { + $this->readmeGenerator->fillClerkAuthType(); + } + } + + $this->readmeGenerator->save(); + + $this->info('README generated successfully!'); + + if ($this->emptyValuesList) { + $this->warn('Don`t forget to fill the following empty values:'); + + foreach ($this->emptyValuesList as $value) { + $this->warn("- {$value}"); + } + } } protected function fillResources(): void { - $filePart = $this->loadReadmePart('RESOURCES.md'); + $filePart = $this->readmeGenerator->loadReadmePart('RESOURCES.md'); $laterText = '(will be added later)'; foreach (self::RESOURCES_ITEMS as $key => $title) { @@ -383,82 +415,67 @@ protected function fillResources(): void if ($link === 'later') { $this->emptyValuesList[] = "{$title} link"; - $this->setReadmeValue($filePart, "{$key}_link"); - $this->setReadmeValue($filePart, "{$key}_later", $laterText); + $this->readmeGenerator->setReadmeValue($filePart, "{$key}_link"); + $this->readmeGenerator->setReadmeValue($filePart, "{$key}_later", $laterText); } elseif ($link !== 'no') { - $this->setReadmeValue($filePart, "{$key}_link", $link); - $this->setReadmeValue($filePart, "{$key}_later"); + $this->readmeGenerator->setReadmeValue($filePart, "{$key}_link", $link); + $this->readmeGenerator->setReadmeValue($filePart, "{$key}_later"); } $this->resources[$key] = ($link !== 'no'); - $this->removeTag($filePart, $key, $link === 'no'); + $this->readmeGenerator->removeTag($filePart, $key, $link === 'no'); } - $this->setReadmeValue($filePart, 'api_link', $this->appUrl); - $this->updateReadmeFile($filePart); + $this->readmeGenerator->setReadmeValue($filePart, 'api_link', $this->appUrl); + $this->readmeGenerator->updateReadmeFile($filePart); } protected function fillContacts(): void { - $filePart = $this->loadReadmePart('CONTACTS.md'); + $filePart = $this->readmeGenerator->loadReadmePart('CONTACTS.md'); foreach (self::CONTACTS_ITEMS as $key => $title) { if ($link = $this->ask("Please enter a {$title}'s email", '')) { - $this->setReadmeValue($filePart, "{$key}_link", $link); + $this->readmeGenerator->setReadmeValue($filePart, "{$key}_link", $link); } else { $this->emptyValuesList[] = "{$title}'s email"; } - $this->removeTag($filePart, $key); + $this->readmeGenerator->removeTag($filePart, $key); } - $this->setReadmeValue($filePart, 'team_lead_link', $this->codeOwnerEmail); + $this->readmeGenerator->setReadmeValue($filePart, 'team_lead_link', $this->codeOwnerEmail); - $this->updateReadmeFile($filePart); - } - - protected function fillPrerequisites(): void - { - $filePart = $this->loadReadmePart('PREREQUISITES.md'); - - $this->updateReadmeFile($filePart); + $this->readmeGenerator->updateReadmeFile($filePart); } protected function fillGettingStarted(): void { $gitProjectPath = trim((string) shell_exec('git ls-remote --get-url origin')); $projectDirectory = basename($gitProjectPath, '.git'); - $filePart = $this->loadReadmePart('GETTING_STARTED.md'); + $filePart = $this->readmeGenerator->loadReadmePart('GETTING_STARTED.md'); - $this->setReadmeValue($filePart, 'git_project_path', $gitProjectPath); - $this->setReadmeValue($filePart, 'project_directory', $projectDirectory); + $this->readmeGenerator->setReadmeValue($filePart, 'git_project_path', $gitProjectPath); + $this->readmeGenerator->setReadmeValue($filePart, 'project_directory', $projectDirectory); - $this->updateReadmeFile($filePart); + $this->readmeGenerator->updateReadmeFile($filePart); } - protected function fillEnvironments(): void + protected function fillCredentialsAndAccess(): void { - $filePart = $this->loadReadmePart('ENVIRONMENTS.md'); - - $this->setReadmeValue($filePart, 'api_link', $this->appUrl); - $this->updateReadmeFile($filePart); - } - - protected function fillCredentialsAndAccess(string $kebabName): void - { - $filePart = $this->loadReadmePart('CREDENTIALS_AND_ACCESS.md'); + $filePart = $this->readmeGenerator->loadReadmePart('CREDENTIALS_AND_ACCESS.md'); if (!empty($this->adminCredentials)) { - $this->setReadmeValue($filePart, 'admin_email', $this->adminCredentials['email']); - $this->setReadmeValue($filePart, 'admin_password', $this->adminCredentials['password']); + $this->readmeGenerator->setReadmeValue($filePart, 'admin_email', $this->adminCredentials['email']); + $this->readmeGenerator->setReadmeValue($filePart, 'admin_password', $this->adminCredentials['password']); } - $this->removeTag($filePart, 'admin_credentials', !$this->adminCredentials); + $this->readmeGenerator->removeTag($filePart, 'admin_credentials', !$this->adminCredentials); foreach (self::CREDENTIALS_ITEMS as $key => $title) { if (!Arr::get($this->resources, $key)) { - $this->removeTag($filePart, "{$key}_credentials", true); + $this->readmeGenerator->removeTag($filePart, "{$key}_credentials", true); continue; } @@ -470,112 +487,15 @@ protected function fillCredentialsAndAccess(string $kebabName): void $this->publishAdminsTableMigration(); } - $adminCredentials = $this->createAdminUser($kebabName, $key, $title); + $adminCredentials = $this->createAdminUser($key, $title); } - $this->setReadmeValue($filePart, "{$key}_email", $adminCredentials['email']); - $this->setReadmeValue($filePart, "{$key}_password", $adminCredentials['password']); - $this->removeTag($filePart, "{$key}_credentials"); - } - - $this->updateReadmeFile($filePart); - } - - protected function fillClerkAuthType(): void - { - $filePart = $this->loadReadmePart('CLERK.md'); - - $this->updateReadmeFile($filePart); - } - - protected function addQuotes($string): string - { - return (Str::contains($string, ' ')) ? "\"{$string}\"" : $string; - } - - protected function publishClass(View $template, string $fileName, string $filePath): void - { - $fileName = "{$fileName}.php"; - - if (!is_dir($filePath)) { - mkdir($filePath, 0777, true); + $this->readmeGenerator->setReadmeValue($filePart, "{$key}_email", $adminCredentials['email']); + $this->readmeGenerator->setReadmeValue($filePart, "{$key}_password", $adminCredentials['password']); + $this->readmeGenerator->removeTag($filePart, "{$key}_credentials"); } - $data = $template->render(); - - file_put_contents("{$filePath}/{$fileName}", "format('Y_m_d_His'); - - $migrationName = "{$time}_{$migrationName}"; - - $this->publishClass($view, $migrationName, 'database/migrations'); - } - - protected function updateEnvFile(string $fileName, array $data): void - { - $env = EnvFile::open($fileName); - - // TODO: After updating wintercms/laravel-config-writer, remove the key comparison check and keep only $env->addEmptyLine(); - $envKeys = array_column($env->getAst(), 'match'); - $dataKeys = array_keys($data); - - $hasMissingKeys = count(array_intersect($dataKeys, $envKeys)) !== count($dataKeys); - - if ($hasMissingKeys) { - $env->addEmptyLine(); - } - - $env->set($data); - - $env->write(); - } - - protected function loadReadmePart(string $fileName): string - { - $file = base_path(DIRECTORY_SEPARATOR . self::TEMPLATES_PATH . DIRECTORY_SEPARATOR . $fileName); - - return file_get_contents($file); - } - - protected function updateReadmeFile(string $filePart): void - { - $filePart = preg_replace('#(\n){3,}#', "\n", $filePart); - - $this->readmeContent .= "\n" . $filePart; - } - - protected function removeTag(string &$text, string $tag, bool $removeWholeString = false): void - { - $regex = ($removeWholeString) - ? "#({{$tag}})(.|\s)*?({/{$tag}})#" - : "# {0,1}{(/*){$tag}}#"; - - $text = preg_replace($regex, '', $text); - } - - protected function setReadmeValue(string &$file, string $key, string $value = ''): void - { - $file = str_replace(":{$key}", $value, $file); - } - - protected function saveReadme(): void - { - file_put_contents('README.md', $this->readmeContent); - } - - protected function prepareAppName(): void - { - $this->appName = $this->argument('application-name'); - - $pascalCaseAppName = ucfirst(Str::camel($this->appName)); - - if ($this->appName !== $pascalCaseAppName && $this->confirm("The application name is not in PascalCase, would you like to use {$pascalCaseAppName}", true)) { - $this->appName = $pascalCaseAppName; - } + $this->readmeGenerator->updateReadmeFile($filePart); } protected function saveRenovateJSON(): void @@ -596,46 +516,55 @@ protected function saveRenovateJSON(): void file_put_contents('renovate.json', json_encode($data, JSON_PRETTY_PRINT)); } - protected function validateInput(callable $method, string $field, string|array $rules): string + protected function setupComposerHooks(): void { - $value = $method(); + $path = base_path('composer.json'); - $validator = Validator::make([$field => $value], [$field => $rules]); + $content = file_get_contents($path); - if ($validator->fails()) { - $this->warn($validator->errors()->first()); + $data = json_decode($content, true); - $value = $this->validateInput($method, $field, $rules); - } + $this->addArrayItemIfMissing($data, 'extra.hooks.config.stop-on-failure', 'pre-commit'); + $this->addArrayItemIfMissing($data, 'extra.hooks.pre-commit', 'docker compose up -d php && docker compose exec -T nginx vendor/bin/pint --repair'); + $this->addArrayItemIfMissing($data, 'scripts.post-install-cmd', '[ $COMPOSER_DEV_MODE -eq 0 ] || cghooks add --ignore-lock'); + $this->addArrayItemIfMissing($data, 'scripts.post-update-cmd', 'cghooks update'); - return $value; + $resultData = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"; + + file_put_contents($path, $resultData); + } + + protected function addArrayItemIfMissing(array &$data, string $path, string $value): void + { + $current = Arr::get($data, $path, []); + + if (!in_array($value, $current)) { + $current[] = $value; + + Arr::set($data, $path, $current); + } } - protected function fillRenovate(): void + protected function changeMiddlewareForTelescopeAuthorization(): void { - $filePart = $this->loadReadmePart('RENOVATE.md'); + $config = ArrayFile::open(base_path('config/telescope.php')); + + // TODO: add Authorize::class middleware after inplementing an ability to modify functions in the https://github.com/RonasIT/larabuilder package + $config->set('middleware', [ + 'web', + 'auth:web', + ]); - $this->updateReadmeFile($filePart); + $config->write(); } - protected function enableClerk(): void + protected function setAutoDocContactEmail(string $email): void { - array_push( - $this->shellCommands, - 'composer require ronasit/laravel-clerk', - 'php artisan laravel-clerk:install', - ); + $config = ArrayFile::open(base_path('config/auto-doc.php')); - $this->publishMigration( - view: view('initializator::users_add_clerk_id_field'), - migrationName: 'users_add_clerk_id_field', - ); + $config->set('info.contact.email', $email); - $this->publishClass( - template: view('initializator::clerk_user_repository'), - fileName: 'ClerkUserRepository', - filePath: 'app/Support/Clerk', - ); + $config->write(); } protected function publishWebLogin(): void @@ -645,17 +574,21 @@ protected function publishWebLogin(): void file_put_contents(base_path('routes/web.php'), "\nAuth::routes();\n", FILE_APPEND); } - protected function changeMiddlewareForTelescopeAuthorization(): void + protected function runMigrations(): void { - $config = ArrayFile::open(base_path('config/telescope.php')); - - // TODO: add Authorize::class middleware after inplementing an ability to modify functions in the https://github.com/RonasIT/larabuilder package - $config->set('middleware', [ - 'web', - 'auth:web', + config([ + 'database.default' => $this->envConfig['dbConnection'], + 'database.connections.pgsql' => [ + 'driver' => $this->envConfig['dbConnection'], + 'host' => $this->envConfig['dbHost'], + 'port' => $this->envConfig['dbPort'], + 'database' => $this->envConfig['dbName'], + 'username' => $this->envConfig['dbUserName'], + 'password' => '', + ], ]); - $config->write(); + shell_exec('php artisan migrate --ansi'); } protected function publishAdminMigration(array $adminCredentials, ?string $serviceKey): void diff --git a/src/Generators/ReadmeGenerator.php b/src/Generators/ReadmeGenerator.php new file mode 100644 index 0000000..e065e8d --- /dev/null +++ b/src/Generators/ReadmeGenerator.php @@ -0,0 +1,90 @@ +loadReadmePart('README.md'); + + $this->setReadmeValue($file, 'project_name', $appName); + + $this->setReadmeValue($file, 'type', $appType); + + $this->readmeContent = $file; + } + + public function fillResourcesAndContacts(): void + { + $filePart = $this->loadReadmePart('RESOURCES_AND_CONTACTS.md'); + + $this->updateReadmeFile($filePart); + } + + public function fillPrerequisites(): void + { + $filePart = $this->loadReadmePart('PREREQUISITES.md'); + + $this->updateReadmeFile($filePart); + } + + public function fillEnvironments(string $appUrl): void + { + $filePart = $this->loadReadmePart('ENVIRONMENTS.md'); + + $this->setReadmeValue($filePart, 'api_link', $appUrl); + $this->updateReadmeFile($filePart); + } + + public function fillClerkAuthType(): void + { + $filePart = $this->loadReadmePart('CLERK.md'); + + $this->updateReadmeFile($filePart); + } + + public function loadReadmePart(string $fileName): string + { + $file = base_path(self::TEMPLATES_PATH . DIRECTORY_SEPARATOR . $fileName); + + return file_get_contents($file); + } + + public function updateReadmeFile(string $filePart): void + { + $filePart = preg_replace('#(\n){3,}#', "\n", $filePart); + + $this->readmeContent .= "\n" . $filePart; + } + + public function removeTag(string &$text, string $tag, bool $removeWholeString = false): void + { + $regex = ($removeWholeString) + ? "#({{$tag}})(.|\s)*?({/{$tag}})#" + : "# {0,1}{(/*){$tag}}#"; + + $text = preg_replace($regex, '', $text); + } + + public function setReadmeValue(string &$file, string $key, string $value = ''): void + { + $file = str_replace(":{$key}", $value, $file); + } + + public function save(): void + { + file_put_contents('README.md', $this->readmeContent); + } + + public function fillRenovate(): void + { + $filePart = $this->loadReadmePart('RENOVATE.md'); + + $this->updateReadmeFile($filePart); + } +} diff --git a/tests/InitCommandTest.php b/tests/InitCommandTest.php index c077c2f..0186d3e 100644 --- a/tests/InitCommandTest.php +++ b/tests/InitCommandTest.php @@ -221,16 +221,6 @@ public function testRunWithAdminAndDefaultReadmeCreation() $this->callFileExists('.env', false), $this->callFileExists('.env.development'), - $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/PREREQUISITES.md'), $this->getReadmeTemplateContent('PREREQUISITES.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/GETTING_STARTED.md'), $this->getReadmeTemplateContent('GETTING_STARTED.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/ENVIRONMENTS.md'), $this->getReadmeTemplateContent('ENVIRONMENTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CLERK.md'), $this->getReadmeTemplateContent('CLERK.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RENOVATE.md'), $this->getReadmeTemplateContent('RENOVATE.md')), $this->callFileGetContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent('database/migrations/2018_11_11_111111_users_add_clerk_id_field.php', $this->getFixture('users_add_clerk_id_field_migration.php')), @@ -239,9 +229,7 @@ public function testRunWithAdminAndDefaultReadmeCreation() $this->callFilePutContent('database/migrations/2018_11_11_111111_add_default_admin.php', $this->getFixture('admins_add_default_admin.php')), $this->callGlob(base_path('database/migrations/*_admins_create_table.php'), [base_path('database/migrations/2018_11_11_111111_admins_create_table.php')]), $this->callFilePutContent('database/migrations/2018_11_11_111111_add_nova_admin.php', $this->getFixture('admins_add_nova_admin_migration.php')), - $this->callFilePutContent('README.md', $this->getFixture('default_readme.md')), $this->callFilePutContent('renovate.json', $this->getFixture('renovate.json')), - $this->callFilePutContent('README.md', $this->getFixture('default_readme_after_using_renovate.md')), $this->callFilePutContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent(base_path('/routes/web.php'), "\nAuth::routes();\n", FILE_APPEND), @@ -264,6 +252,24 @@ public function testRunWithAdminAndDefaultReadmeCreation() $this->callShellExec('php artisan migrate --ansi'), ); + $this->mockNativeFunction( + 'RonasIT\ProjectInitializator\Generators', + + $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/PREREQUISITES.md'), $this->getReadmeTemplateContent('PREREQUISITES.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/GETTING_STARTED.md'), $this->getReadmeTemplateContent('GETTING_STARTED.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/ENVIRONMENTS.md'), $this->getReadmeTemplateContent('ENVIRONMENTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CLERK.md'), $this->getReadmeTemplateContent('CLERK.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RENOVATE.md'), $this->getReadmeTemplateContent('RENOVATE.md')), + + $this->callFilePutContent('README.md', $this->getFixture('default_readme.md')), + $this->callFilePutContent('README.md', $this->getFixture('default_readme_after_using_renovate.md')), + ); + $this ->artisan('init "My App"') ->expectsConfirmation('The application name is not in PascalCase, would you like to use MyApp') @@ -359,15 +365,8 @@ public function testRunWithAdminAndPartialReadmeCreation() $this->callFileExists('.env', false), $this->callFileExists('.env.development'), - $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/ENVIRONMENTS.md'), $this->getReadmeTemplateContent('ENVIRONMENTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), $this->callFileGetContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), - $this->callFilePutContent('README.md', $this->getFixture('partial_readme.md')), $this->callFilePutContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent(base_path('/routes/web.php'), "\nAuth::routes();\n", FILE_APPEND), @@ -387,6 +386,17 @@ public function testRunWithAdminAndPartialReadmeCreation() $this->callShellExec('php artisan migrate --ansi'), ); + $this->mockNativeFunction( + 'RonasIT\ProjectInitializator\Generators', + $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/ENVIRONMENTS.md'), $this->getReadmeTemplateContent('ENVIRONMENTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), + $this->callFilePutContent('README.md', $this->getFixture('partial_readme.md')), + ); + $this ->artisan('init "My App"') ->expectsConfirmation('The application name is not in PascalCase, would you like to use MyApp') @@ -470,22 +480,11 @@ public function testRunWithAdminAndFullReadmeCreationAndRemovingInitializatorIns $this->callFileExists('.env', false), $this->callFileExists('.env.development'), - $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/PREREQUISITES.md'), $this->getReadmeTemplateContent('PREREQUISITES.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/GETTING_STARTED.md'), $this->getReadmeTemplateContent('GETTING_STARTED.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/ENVIRONMENTS.md'), $this->getReadmeTemplateContent('ENVIRONMENTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RENOVATE.md'), $this->getReadmeTemplateContent('RENOVATE.md')), $this->callFileGetContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent('database/migrations/2018_11_11_111111_add_default_admin.php', $this->getFixture('migration.php')), $this->callFilePutContent('database/migrations/2018_11_11_111111_add_nova_admin.php', $this->getFixture('nova_users_table_migration.php')), - $this->callFilePutContent('README.md', $this->getFixture('full_readme.md')), $this->callFilePutContent('renovate.json', $this->getFixture('renovate.json')), - $this->callFilePutContent('README.md', $this->getFixture('full_readme_after_using_renovate.md')), $this->callFilePutContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent(base_path('/routes/web.php'), "\nAuth::routes();\n", FILE_APPEND), @@ -508,6 +507,21 @@ public function testRunWithAdminAndFullReadmeCreationAndRemovingInitializatorIns $this->callShellExec('php artisan migrate --ansi'), ); + $this->mockNativeFunction( + 'RonasIT\ProjectInitializator\Generators', + $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/PREREQUISITES.md'), $this->getReadmeTemplateContent('PREREQUISITES.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/GETTING_STARTED.md'), $this->getReadmeTemplateContent('GETTING_STARTED.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/ENVIRONMENTS.md'), $this->getReadmeTemplateContent('ENVIRONMENTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RENOVATE.md'), $this->getReadmeTemplateContent('RENOVATE.md')), + $this->callFilePutContent('README.md', $this->getFixture('full_readme.md')), + $this->callFilePutContent('README.md', $this->getFixture('full_readme_after_using_renovate.md')), + ); + $this ->artisan('init "My App"') ->expectsConfirmation('The application name is not in PascalCase, would you like to use MyApp') @@ -600,17 +614,10 @@ public function testRunWithoutAdminAndUsingTelescope() $this->callFileExists('.env', false), $this->callFileExists('.env.development'), - $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/ENVIRONMENTS.md'), $this->getReadmeTemplateContent('ENVIRONMENTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), $this->callFileGetContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent('database/migrations/2018_11_11_111111_add_telescope_admin.php', $this->getFixture('telescope_users_table_migration.php')), $this->callFilePutContent('database/migrations/2018_11_11_111111_add_nova_admin.php', $this->getFixture('nova_users_table_migration.php')), - $this->callFilePutContent('README.md', $this->getFixture('partial_readme_with_telescope.md')), $this->callFilePutContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent(base_path('/routes/web.php'), "\nAuth::routes();\n", FILE_APPEND), @@ -630,6 +637,17 @@ public function testRunWithoutAdminAndUsingTelescope() $this->callShellExec('php artisan migrate --ansi'), ); + $this->mockNativeFunction( + 'RonasIT\ProjectInitializator\Generators', + $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/ENVIRONMENTS.md'), $this->getReadmeTemplateContent('ENVIRONMENTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), + $this->callFilePutContent('README.md', $this->getFixture('partial_readme_with_telescope.md')), + ); + $this ->artisan('init "My App"') ->expectsConfirmation('The application name is not in PascalCase, would you like to use MyApp') @@ -723,25 +741,13 @@ public function testRunWithClerkMobileAppWithPintInstalled(): void $this->callFileExists('.env', false), $this->callFileExists('.env.development'), - $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/PREREQUISITES.md'), $this->getReadmeTemplateContent('PREREQUISITES.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/GETTING_STARTED.md'), $this->getReadmeTemplateContent('GETTING_STARTED.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/ENVIRONMENTS.md'), $this->getReadmeTemplateContent('ENVIRONMENTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CLERK.md'), $this->getReadmeTemplateContent('CLERK.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RENOVATE.md'), $this->getReadmeTemplateContent('RENOVATE.md')), $this->callFileGetContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent('database/migrations/2018_11_11_111111_users_add_clerk_id_field.php', $this->getFixture('users_add_clerk_id_field_migration.php')), $this->callFilePutContent('app/Support/Clerk/ClerkUserRepository.php', $this->getFixture('clerk_user_repository.php')), $this->callFilePutContent('database/migrations/2018_11_11_111111_admins_create_table.php', $this->getFixture('admins_table_migration.php')), $this->callFilePutContent('database/migrations/2018_11_11_111111_add_default_admin.php', $this->getFixture('admins_add_default_admin.php')), - $this->callFilePutContent('README.md', $this->getFixture('default_readme_with_mobile_app.md')), $this->callFilePutContent('renovate.json', $this->getFixture('renovate.json')), - $this->callFilePutContent('README.md', $this->getFixture('default_readme_with_mobile_app_after_using_renovate.md')), $this->callFilePutContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent(base_path('/routes/web.php'), "\nAuth::routes();\n", FILE_APPEND), @@ -764,6 +770,22 @@ public function testRunWithClerkMobileAppWithPintInstalled(): void $this->callShellExec('php artisan migrate --ansi'), ); + $this->mockNativeFunction( + 'RonasIT\ProjectInitializator\Generators', + $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/PREREQUISITES.md'), $this->getReadmeTemplateContent('PREREQUISITES.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/GETTING_STARTED.md'), $this->getReadmeTemplateContent('GETTING_STARTED.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/ENVIRONMENTS.md'), $this->getReadmeTemplateContent('ENVIRONMENTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CLERK.md'), $this->getReadmeTemplateContent('CLERK.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RENOVATE.md'), $this->getReadmeTemplateContent('RENOVATE.md')), + $this->callFilePutContent('README.md', $this->getFixture('default_readme_with_mobile_app.md')), + $this->callFilePutContent('README.md', $this->getFixture('default_readme_with_mobile_app_after_using_renovate.md')), + ); + $this ->artisan('init "My App"') ->expectsConfirmation('The application name is not in PascalCase, would you like to use MyApp') @@ -859,13 +881,7 @@ public function testRunWithClerkAdditionalAdminsWithoutDefaultAdmin(): void $this->callFileExists('.env', false), $this->callFileExists('.env.development'), - $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), - $this->callFileGetContent($this->generateResourcePath('md/readme/CLERK.md'), $this->getReadmeTemplateContent('CLERK.md')), - $this->callFileGetContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), + $this->callFileGetContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent('database/migrations/2018_11_11_111111_users_add_clerk_id_field.php', $this->getFixture('users_add_clerk_id_field_migration.php')), $this->callFilePutContent('app/Support/Clerk/ClerkUserRepository.php', $this->getFixture('clerk_user_repository.php')), @@ -874,7 +890,6 @@ public function testRunWithClerkAdditionalAdminsWithoutDefaultAdmin(): void $this->callFilePutContent('database/migrations/2018_11_11_111111_add_telescope_admin.php', $this->getFixture('admins_add_telescope_admin_migration.php')), $this->callGlob(base_path('database/migrations/*_admins_create_table.php'), [base_path('database/migrations/2018_11_11_111111_admins_create_table.php')]), $this->callFilePutContent('database/migrations/2018_11_11_111111_add_nova_admin.php', $this->getFixture('admins_add_nova_admin_migration.php')), - $this->callFilePutContent('README.md', $this->getFixture('partial_readme_clerk_with_credentials.md')), $this->callFilePutContent(base_path('composer.json'), $this->getFixture('composer_with_pint_settings.json')), $this->callFilePutContent(base_path('/routes/web.php'), "\nAuth::routes();\n", FILE_APPEND), @@ -896,6 +911,18 @@ public function testRunWithClerkAdditionalAdminsWithoutDefaultAdmin(): void $this->callShellExec('php artisan migrate --ansi'), ); + $this->mockNativeFunction( + 'RonasIT\ProjectInitializator\Generators', + $this->callFileGetContent($this->generateResourcePath('md/readme/README.md'), $this->getReadmeTemplateContent('README.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES_AND_CONTACTS.md'), $this->getReadmeTemplateContent('RESOURCES_AND_CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/RESOURCES.md'), $this->getReadmeTemplateContent('RESOURCES.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CONTACTS.md'), $this->getReadmeTemplateContent('CONTACTS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CREDENTIALS_AND_ACCESS.md'), $this->getReadmeTemplateContent('CREDENTIALS_AND_ACCESS.md')), + $this->callFileGetContent($this->generateResourcePath('md/readme/CLERK.md'), $this->getReadmeTemplateContent('CLERK.md')), + + $this->callFilePutContent('README.md', $this->getFixture('partial_readme_clerk_with_credentials.md')), + ); + $this ->artisan('init "My App"') ->expectsConfirmation('The application name is not in PascalCase, would you like to use MyApp')