Files
Gnuboard7/app/Console/Commands/ConvertPHPUnitAnnotations.php
T
2026-04-01 10:30:52 +09:00

219 lines
6.5 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
/**
* PHPUnit Doc-Comment Annotations를 PHP 8 Attributes로 변환하는 Artisan 커맨드
*
* @package App\Console\Commands
* @author sirsoft
*/
class ConvertPHPUnitAnnotations extends Command
{
/**
* 커맨드 시그니처
*
* @var string
*/
protected $signature = 'phpunit:convert-annotations
{--dry-run : 변환 미리보기 (파일 수정 안 함)}
{--backup : 변환 전 백업 생성 (.bak 파일)}
{--path= : 특정 경로만 변환}
{--stats-only : 통계만 출력}
{--rollback : 백업에서 복원}';
/**
* 커맨드 설명
*
* @var string
*/
protected $description = 'PHPUnit doc-comment annotations를 PHP 8 attributes로 변환합니다';
/**
* 변환기 인스턴스
*
* @var mixed
*/
private $converter;
/**
* 커맨드를 실행합니다.
*
* @return int 종료 코드
*/
public function handle(): int
{
// 스크립트 파일 로드
$scriptPath = base_path('scripts/convert-phpunit-annotations.php');
if (!file_exists($scriptPath)) {
$this->error("스크립트 파일을 찾을 수 없습니다: {$scriptPath}");
return Command::FAILURE;
}
require_once $scriptPath;
// 롤백 모드
if ($this->option('rollback')) {
return $this->handleRollback();
}
// 통계만 확인
if ($this->option('stats-only')) {
return $this->handleStatsOnly();
}
// 변환 실행
return $this->handleConversion();
}
/**
* 통계만 확인합니다.
*
* @return int 종료 코드
*/
private function handleStatsOnly(): int
{
$this->info('PHPUnit Annotation 통계 확인 중...');
$this->newLine();
$converter = new \PHPUnitAnnotationConverter(false, false, false);
$basePath = base_path();
$specificPath = $this->option('path');
$stats = $converter->getStats($basePath, $specificPath);
$this->line('PHPUnit Annotation Conversion Statistics');
$this->line('=========================================');
$this->line("총 테스트 파일: {$stats['total_files']}");
$this->line("Annotations이 있는 파일: {$stats['files_with_annotations']}");
$this->newLine();
$this->line('Annotation 분류:');
$this->line("- @test: {$stats['test']}");
$this->line("- @dataProvider: {$stats['dataProvider']}");
$this->line("- @group: {$stats['group']}");
$this->line("- @depends: {$stats['depends']}");
$this->newLine();
if (!empty($stats['files'])) {
$this->line('파일별 상세:');
foreach ($stats['files'] as $fileInfo) {
$relativePath = str_replace(base_path() . DIRECTORY_SEPARATOR, '', $fileInfo['path']);
$this->line(" {$relativePath}");
foreach ($fileInfo['annotations'] as $annotation) {
$this->line(" - {$annotation}");
}
}
}
return Command::SUCCESS;
}
/**
* 변환을 실행합니다.
*
* @return int 종료 코드
*/
private function handleConversion(): int
{
$dryRun = $this->option('dry-run');
$backup = $this->option('backup');
$verbose = $this->option('verbose');
if ($dryRun) {
$this->warn('[DRY RUN] 변환 미리보기 모드 - 실제 파일은 수정되지 않습니다');
$this->newLine();
}
if ($backup && !$dryRun) {
$this->info('백업 모드 활성화 - 변환 전 .bak 파일이 생성됩니다');
$this->newLine();
}
$this->converter = new \PHPUnitAnnotationConverter($dryRun, $backup, $verbose);
$basePath = base_path();
$specificPath = $this->option('path');
// 파일 스캔
$this->info('테스트 파일 스캔 중...');
$files = $this->converter->scanTestFiles($basePath, $specificPath);
if (empty($files)) {
$this->warn('변환할 테스트 파일을 찾을 수 없습니다.');
return Command::SUCCESS;
}
$this->info('총 ' . count($files) . '개의 테스트 파일을 발견했습니다.');
$this->newLine();
// 프로그레스 바 생성
$bar = $this->output->createProgressBar(count($files));
$bar->setFormat(' %current%/%max% [%bar%] %percent:3s%% %message%');
$bar->setMessage('변환 시작...');
if (!$verbose) {
$bar->start();
}
$convertedCount = 0;
foreach ($files as $file) {
$relativePath = str_replace(base_path() . DIRECTORY_SEPARATOR, '', $file);
if ($verbose) {
$this->line("처리 중: {$relativePath}");
} else {
$bar->setMessage($relativePath);
}
if ($this->converter->convertFile($file)) {
$convertedCount++;
}
if (!$verbose) {
$bar->advance();
}
}
if (!$verbose) {
$bar->finish();
$this->newLine(2);
}
// 결과 출력
$report = $this->converter->generateReport();
$this->line($report);
if ($dryRun) {
$this->info('Dry-run 완료 - 실제 파일은 변경되지 않았습니다.');
$this->info('실제 변환을 수행하려면 --dry-run 옵션 없이 실행하세요.');
} else {
$this->info('변환 완료!');
if ($backup) {
$this->info('.bak 백업 파일이 생성되었습니다.');
$this->warn('테스트 실행 후 문제가 없으면 백업 파일을 삭제하세요:');
$this->line(' find tests modules plugins -name "*.bak" -delete');
}
}
return Command::SUCCESS;
}
/**
* 백업에서 복원합니다.
*
* @return int 종료 코드
*/
private function handleRollback(): int
{
$this->warn('백업 복원 기능은 현재 구현되지 않았습니다.');
$this->info('수동으로 .bak 파일을 복원하세요:');
$this->line(' for file in $(find . -name "*.bak"); do mv "$file" "${file%.bak}"; done');
return Command::SUCCESS;
}
}