2024-02-21 12:48:33 +00:00
< ? php
namespace App\Console\Command ;
2024-02-21 23:32:59 +00:00
use App\Enum\ProjectLanguage ;
2024-02-21 12:48:33 +00:00
use App\Process\Process ;
use Symfony\Component\Console\Command\Command ;
use Symfony\Component\Console\Input\InputInterface ;
use Symfony\Component\Console\Output\OutputInterface ;
2024-02-21 23:32:59 +00:00
use Symfony\Component\Filesystem\Filesystem ;
2024-02-21 12:48:33 +00:00
final class InstallCommand extends AbstractCommand
{
public function execute ( InputInterface $input , OutputInterface $output ) : int
{
2024-02-21 13:22:17 +00:00
$extraArgs = $input -> getOption ( 'extra-args' );
$workingDir = $input -> getOption ( 'working-dir' );
2024-02-21 12:48:33 +00:00
2024-02-21 23:32:59 +00:00
// TODO: What to do if a project contains multiple languages?
// e.g. a composer.lock file (PHP) and pnpm-lock.yaml file (JS)?
// TODO: validate the language is an allowed value.
2024-02-22 00:31:29 +00:00
$filesystem = new Filesystem ();
2024-02-21 12:48:33 +00:00
// TODO: Composer in Docker Compose?
$process = Process :: create (
2024-02-21 23:32:59 +00:00
command : $this -> getCommand (
2024-02-22 00:31:29 +00:00
filesystem : $filesystem ,
language : $this -> getProjectLanguage ( $filesystem , $workingDir , $input ),
2024-02-21 23:32:59 +00:00
workingDir : $workingDir ,
),
2024-02-22 19:22:42 +00:00
extraArgs : explode ( separator : ' ' , string : $extraArgs ),
2024-02-21 13:22:17 +00:00
workingDir : $workingDir ,
2024-02-21 12:48:33 +00:00
);
2024-02-21 13:20:41 +00:00
$process -> setTimeout ( null );
2024-02-21 12:48:33 +00:00
$process -> run ();
return Command :: SUCCESS ;
}
2024-02-21 23:32:59 +00:00
/**
2024-02-22 00:31:29 +00:00
* @ param Filesystem $filesystem
2024-02-21 23:32:59 +00:00
* @ param non - empty - string $language
* @ param non - empty - string $workingDir
* @ return non - empty - array < int , non - empty - string >
*/
2024-02-22 00:31:29 +00:00
private function getCommand ( Filesystem $filesystem , string $language , string $workingDir ) : array
2024-02-21 23:32:59 +00:00
{
if ( $language === ProjectLanguage :: JavaScript -> value ) {
if ( $filesystem -> exists ( $workingDir . '/yarn.lock' )) {
return [ 'yarn' ];
} elseif ( $filesystem -> exists ( $workingDir . '/pnpm-lock.yaml' )) {
return [ 'pnpm' , 'install' ];
} else {
return [ 'npm' , 'install' ];
}
}
return [ 'composer' , 'install' ];
}
2024-02-22 00:31:29 +00:00
/**
* @ param Filesystem $filesystem
* @ param non - empty - string $workingDir
* @ param InputInterface $input
* @ return non - empty - string
*/
private function getProjectLanguage ( Filesystem $filesystem , string $workingDir , InputInterface $input ) : string {
$projectLanguage = null ;
// Determine the language based on the files.
if ( $filesystem -> exists ( $workingDir . '/composer.json' )) {
$projectLanguage = ProjectLanguage :: PHP -> value ;
} elseif ( $filesystem -> exists ( $workingDir . '/package.json' )) {
$projectLanguage = ProjectLanguage :: JavaScript -> value ;
}
return $input -> getOption ( 'language' ) ? ? $projectLanguage ;
}
2024-02-21 12:48:33 +00:00
}