ogcore/src/Command/CreateImageRepositoriesComm...

286 lines
13 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Command;
use App\Entity\Image;
use App\Entity\ImageRepository;
use App\Entity\ImageImageRepository;
use App\Model\ImageStatus;
use App\Repository\ImageRepository as ImageRepositoryRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
#[AsCommand(
name: 'app:create-image-repositories',
description: 'Crea una ImageRepository y/o ImageImageRepository con datos interactivos'
)]
class CreateImageRepositoriesCommand extends Command
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly ImageRepositoryRepository $imageRepository
) {
parent::__construct();
}
protected function configure(): void
{
$this
->setDescription('Crea una ImageRepository y/o ImageImageRepository')
->addArgument('action', InputArgument::OPTIONAL, 'Acción a realizar: repository, image-repository, o both', 'both')
->addOption('repository-name', null, InputOption::VALUE_OPTIONAL, 'Nombre del repositorio de imágenes')
->addOption('repository-ip', null, InputOption::VALUE_OPTIONAL, 'IP del repositorio de imágenes')
->addOption('repository-user', null, InputOption::VALUE_OPTIONAL, 'Usuario del repositorio', ImageRepository::DEFAULT_USER)
->addOption('repository-ssh-port', null, InputOption::VALUE_OPTIONAL, 'Puerto SSH del repositorio')
->addOption('repository-comments', null, InputOption::VALUE_OPTIONAL, 'Comentarios del repositorio')
->addOption('image-name', null, InputOption::VALUE_OPTIONAL, 'Nombre de la imagen')
->addOption('image-type', null, InputOption::VALUE_OPTIONAL, 'Tipo de imagen', 'Server')
->addOption('image-version', null, InputOption::VALUE_OPTIONAL, 'Versión de la imagen', '1')
->addOption('image-repository-name', null, InputOption::VALUE_OPTIONAL, 'Nombre para ImageImageRepository')
->addOption('image-repository-status', null, InputOption::VALUE_OPTIONAL, 'Status para ImageImageRepository', ImageStatus::SUCCESS)
->addOption('batch', 'b', InputOption::VALUE_NONE, 'Modo no interactivo (usar solo opciones)');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$action = $input->getArgument('action');
$batchMode = $input->getOption('batch');
$helper = $this->getHelper('question');
$output->writeln('<info>🚀 Creador de ImageRepository e ImageImageRepository</info>');
$output->writeln('');
try {
switch ($action) {
case 'repository':
$imageRepository = $this->createImageRepository($input, $output, $helper, $batchMode);
$output->writeln("<success>✅ ImageRepository creado exitosamente: {$imageRepository->getName()}</success>");
break;
case 'image-repository':
$imageImageRepository = $this->createImageImageRepository($input, $output, $helper, $batchMode);
$output->writeln("<success>✅ ImageImageRepository creado exitosamente: {$imageImageRepository->getName()}</success>");
break;
case 'both':
default:
$output->writeln('<comment>Creando ImageRepository primero...</comment>');
$imageRepository = $this->createImageRepository($input, $output, $helper, $batchMode);
$output->writeln("<success>✅ ImageRepository creado: {$imageRepository->getName()}</success>");
$output->writeln('');
$output->writeln('<comment>Ahora creando ImageImageRepository...</comment>');
$imageImageRepository = $this->createImageImageRepository($input, $output, $helper, $batchMode, $imageRepository);
$output->writeln("<success>✅ ImageImageRepository creado: {$imageImageRepository->getName()}</success>");
break;
}
$this->entityManager->flush();
$output->writeln('');
$output->writeln('<success>🎉 ¡Proceso completado exitosamente!</success>');
return Command::SUCCESS;
} catch (\Exception $e) {
$output->writeln("<error>❌ Error: {$e->getMessage()}</error>");
return Command::FAILURE;
}
}
private function createImageRepository(InputInterface $input, OutputInterface $output, $helper, bool $batchMode): ImageRepository
{
// Recopilar datos para ImageRepository
$name = $input->getOption('repository-name');
if (!$name && !$batchMode) {
$question = new Question('<question>Nombre del repositorio de imágenes: </question>');
$question->setValidator(function ($value) {
if (empty($value)) {
throw new \RuntimeException('El nombre no puede estar vacío');
}
return $value;
});
$name = $helper->ask($input, $output, $question);
}
$ip = $input->getOption('repository-ip');
if (!$ip && !$batchMode) {
$question = new Question('<question>IP del repositorio: </question>');
$question->setValidator(function ($value) {
if (empty($value)) {
throw new \RuntimeException('La IP no puede estar vacía');
}
if (!filter_var($value, FILTER_VALIDATE_IP)) {
throw new \RuntimeException('La IP no es válida');
}
return $value;
});
$ip = $helper->ask($input, $output, $question);
}
$user = $input->getOption('repository-user') ?: ImageRepository::DEFAULT_USER;
if (!$batchMode) {
$question = new Question("<question>Usuario [{$user}]: </question>", $user);
$user = $helper->ask($input, $output, $question);
}
$sshPort = $input->getOption('repository-ssh-port');
if (!$sshPort && !$batchMode) {
$question = new Question('<question>Puerto SSH [22]: </question>', '22');
$sshPort = $helper->ask($input, $output, $question);
}
$comments = $input->getOption('repository-comments');
if (!$comments && !$batchMode) {
$question = new Question('<question>Comentarios (opcional): </question>');
$comments = $helper->ask($input, $output, $question);
}
// Crear ImageRepository
$imageRepository = new ImageRepository();
$imageRepository->setName($name);
$imageRepository->setIp($ip);
$imageRepository->setUser($user);
$imageRepository->setSshPort($sshPort);
if ($comments) {
$imageRepository->setComments($comments);
}
$this->entityManager->persist($imageRepository);
return $imageRepository;
}
private function createImageImageRepository(InputInterface $input, OutputInterface $output, $helper, bool $batchMode, ?ImageRepository $repository = null): ImageImageRepository
{
// Si no tenemos repository, necesitamos seleccionar uno existente
if (!$repository) {
$repositories = $this->imageRepository->findAll();
if (empty($repositories)) {
throw new \RuntimeException('No hay ImageRepositories disponibles. Crea uno primero.');
}
if (!$batchMode) {
$output->writeln('<comment>Repositorios disponibles:</comment>');
foreach ($repositories as $i => $repo) {
$output->writeln(" [{$i}] {$repo->getName()} ({$repo->getIp()})");
}
$question = new Question('<question>Selecciona un repositorio (número): </question>');
$question->setValidator(function ($value) use ($repositories) {
if (!is_numeric($value) || !isset($repositories[$value])) {
throw new \RuntimeException('Selección inválida');
}
return (int)$value;
});
$repoIndex = $helper->ask($input, $output, $question);
$repository = $repositories[$repoIndex];
} else {
$repository = $repositories[0]; // Usar el primero disponible en modo batch
}
}
// Obtener todas las imágenes disponibles
$images = $this->entityManager->getRepository(Image::class)->findAll();
$image = null;
if (!empty($images) && !$batchMode) {
$output->writeln('<comment>Imágenes disponibles:</comment>');
foreach ($images as $i => $img) {
$output->writeln(" [{$i}] {$img->getName()} (Tipo: {$img->getType()})");
}
$output->writeln(" [new] Crear nueva imagen");
$question = new Question('<question>Selecciona una imagen o "new" para crear nueva: </question>');
$imageChoice = $helper->ask($input, $output, $question);
if ($imageChoice !== 'new' && is_numeric($imageChoice) && isset($images[$imageChoice])) {
$image = $images[$imageChoice];
}
}
// Si no hay imagen seleccionada, crear una nueva
if (!$image) {
$imageName = $input->getOption('image-name');
if (!$imageName && !$batchMode) {
$question = new Question('<question>Nombre de la imagen: </question>');
$question->setValidator(function ($value) {
if (empty($value)) {
throw new \RuntimeException('El nombre de la imagen no puede estar vacío');
}
return $value;
});
$imageName = $helper->ask($input, $output, $question);
}
$imageType = $input->getOption('image-type') ?: 'Server';
if (!$batchMode) {
$question = new Question("<question>Tipo de imagen [{$imageType}]: </question>", $imageType);
$imageType = $helper->ask($input, $output, $question);
}
$imageVersion = $input->getOption('image-version') ?: 1;
if (!$batchMode) {
$question = new Question("<question>Versión de la imagen [{$imageVersion}]: </question>", $imageVersion);
$imageVersion = (int)$helper->ask($input, $output, $question);
}
// Crear nueva imagen
$image = new Image();
$image->setName($imageName);
$image->setType($imageType);
$image->setVersion($imageVersion);
$image->setRemotePc(false);
$image->setIsGlobal(true);
$this->entityManager->persist($image);
}
// Recopilar datos para ImageImageRepository
$imageRepositoryName = $input->getOption('image-repository-name');
if (!$imageRepositoryName && !$batchMode) {
$defaultName = $image->getName() . '_' . $repository->getName();
$question = new Question("<question>Nombre para ImageImageRepository [{$defaultName}]: </question>", $defaultName);
$imageRepositoryName = $helper->ask($input, $output, $question);
} elseif (!$imageRepositoryName) {
$imageRepositoryName = $image->getName() . '_' . $repository->getName();
}
$status = $input->getOption('image-repository-status') ?: ImageStatus::SUCCESS;
if (!$batchMode) {
$output->writeln('<comment>Status disponibles:</comment>');
foreach (ImageStatus::getStatusKeys() as $statusKey) {
$output->writeln(" - {$statusKey}");
}
$question = new Question("<question>Status [{$status}]: </question>", $status);
$question->setValidator(function ($value) {
if (!in_array($value, ImageStatus::getStatusKeys())) {
throw new \RuntimeException('Status inválido');
}
return $value;
});
$status = $helper->ask($input, $output, $question);
}
// Crear ImageImageRepository
$imageImageRepository = new ImageImageRepository();
$imageImageRepository->setName($imageRepositoryName);
$imageImageRepository->setImage($image);
$imageImageRepository->setRepository($repository);
$imageImageRepository->setStatus($status);
$imageImageRepository->setCreated(true);
$imageImageRepository->setVersion($image->getVersion());
$this->entityManager->persist($imageImageRepository);
return $imageImageRepository;
}
}