argument('identifier'); // 식별자 형식 검증 $validator = Validator::make( ['identifier' => $identifier], ['identifier' => [new ValidExtensionIdentifier]] ); if ($validator->fails()) { $this->error('❌ '.$validator->errors()->first('identifier')); return Command::FAILURE; } $force = (bool) $this->option('force'); try { // 템플릿 디렉토리 스캔 및 로드 $this->templateManager->loadTemplates(); // 이미 설치된 템플릿인지 확인 (force 시 경고 후 재설치/복구 허용) $existingTemplate = $this->templateRepository->findByIdentifier($identifier); if ($existingTemplate && $force) { $this->warn('⚠️ '.__('templates.commands.install.force_reinstall', ['template' => $identifier])); } // 템플릿 설치 $onProgress = $this->createProgressCallback(TemplateManager::INSTALL_STEPS); try { $result = $this->templateManager->installTemplate($identifier, $onProgress, $force); $this->finishProgress(); } catch (\Exception $e) { $this->finishProgress(); throw $e; } if ($result) { // 설치된 템플릿 정보 조회 $template = $this->templateRepository->findByIdentifier($identifier); // 성공 메시지 $this->info('✅ '.__('templates.commands.install.success', ['template' => $identifier])); $this->info(' - '.__('templates.commands.install.type', ['type' => __('templates.types.'.$template->type)])); $this->info(' - '.__('templates.commands.install.version', ['version' => $template->version])); $this->info(' - '.__('templates.commands.install.layouts_created', ['count' => $template->layouts()->count()])); Log::info(__('templates.commands.install.success', ['template' => $identifier])); return Command::SUCCESS; } return Command::FAILURE; } catch (\Exception $e) { $this->error('❌ '.$e->getMessage()); Log::error('템플릿 설치 실패', [ 'template' => $identifier, 'error' => $e->getMessage(), ]); return Command::FAILURE; } } }