diff --git a/src/Commands/ClonePackageCommand.php b/src/Commands/ClonePackageCommand.php new file mode 100644 index 0000000..c89d3a8 --- /dev/null +++ b/src/Commands/ClonePackageCommand.php @@ -0,0 +1,121 @@ +argument('url'); + + try { + $packageName = $this->getPackageName($url); + + $destination = "composer-packages/ibecsystems/{$packageName}"; + + if (! $this->hasPackage($destination)) { + $this->comment("Cloning package...\n"); + $this->clonePackage($url, $destination); + } else { + $this->comment('Package already cloned. Skipping...'); + } + + if ($this->hasPHPStormConfig()) { + if (! $this->hasDirectoryMapping($destination)) { + $this->comment("[PHPStorm] Adding Directory Mapping...\n"); + $this->addDirectoryMapping($destination); + } else { + $this->comment('[PHPStorm] Directory Mapping already added. Skipping...'); + } + } + + $this->info("Package ready for development: {$destination}"); + } catch (Exception $exception) { + $this->error($exception->getMessage()); + } + } + + /** + * @throws Exception + */ + private function getPackageName(string $url): string + { + $repoName = explode('/', $url)[1] ?? null; + + if (! $repoName) { + throw new Exception("Invalid repository url: {$url}"); + } + + if (str_contains($repoName, '.git')) { + $repoName = str_replace('.git', '', $repoName); + } + + if (! is_string($repoName)) { + throw new Exception("Error while parsing repository url: {$url}"); + } + + return $repoName; + } + + private function hasPackage(string $destination): bool + { + return File::isDirectory(base_path($destination)); + } + + /** + * @throws Exception + */ + private function clonePackage(string $url, string $destination): void + { + try { + Process::run("git clone {$url} {$destination}") + ->throw(); + } catch (ProcessFailedException $e) { + throw new Exception('Cannot clone package: '.$e->getMessage()); + } + } + + private function hasPHPStormConfig(): bool + { + return File::isDirectory(base_path('.idea')); + } + + /** + * @throws Exception + */ + private function hasDirectoryMapping(string $destination): bool + { + $vcsPath = base_path('.idea/vcs.xml'); + + $xml = simplexml_load_file($vcsPath); + + $mapping = $xml->xpath("//mapping[@directory='\$PROJECT_DIR\$/{$destination}']"); + + return (bool) $mapping; + } + + private function addDirectoryMapping(string $destination): void + { + $vcsPath = base_path('.idea/vcs.xml'); + + $xml = simplexml_load_file($vcsPath); + + $components = $xml->xpath('//component[@name="VcsDirectoryMappings"]'); + + $mapping = $components[0]->addChild('mapping'); + $mapping->addAttribute('directory', "\$PROJECT_DIR\$/{$destination}"); + $mapping->addAttribute('vcs', 'Git'); + + $xml->asXML($vcsPath); + } +} diff --git a/src/CoreServiceProvider.php b/src/CoreServiceProvider.php index 291adc0..ef5b808 100644 --- a/src/CoreServiceProvider.php +++ b/src/CoreServiceProvider.php @@ -2,6 +2,7 @@ namespace AdminKit\Core; +use AdminKit\Core\Commands\ClonePackageCommand; use AdminKit\Core\Commands\InstallCommand; use AdminKit\Core\Providers\FilamentServiceProvider; use AdminKit\Core\Providers\MiddlewareServiceProvider; @@ -24,7 +25,10 @@ public function configurePackage(Package $package): void ->hasMigration('create_admin_kit_users_table') ->hasTranslations() ->hasRoute('api') - ->hasCommand(InstallCommand::class); + ->hasCommands([ + InstallCommand::class, + ClonePackageCommand::class, + ]); } public function registeringPackage()