2024-02-21 12:48:33 +00:00
< ? php
namespace App\Console\Command ;
2024-02-22 00:31:29 +00:00
use App\Enum\ProjectLanguage ;
2024-02-21 12:48:33 +00:00
use App\Enum\ProjectType ;
use App\Process\Process ;
use RuntimeException ;
use Symfony\Component\Console\Command\Command ;
use Symfony\Component\Console\Input\InputInterface ;
use Symfony\Component\Console\Output\OutputInterface ;
use Symfony\Component\Filesystem\Filesystem ;
final class BuildCommand extends AbstractCommand
{
public function execute ( InputInterface $input , OutputInterface $output ) : int
{
2024-02-22 00:31:29 +00:00
$projectLanguage = null ;
2024-02-21 12:48:33 +00:00
$projectType = null ;
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
$filesystem = new Filesystem ();
// Attempt to prepopulate some of the options, such as the project type
// based on its dependencies.
// TODO: move this logic to a service so it can be tested.
2024-02-21 13:22:17 +00:00
if ( $filesystem -> exists ( $workingDir . '/composer.json' )) {
2024-02-22 00:31:29 +00:00
$projectLanguage = ProjectLanguage :: PHP -> value ;
2024-02-21 12:48:33 +00:00
$json = json_decode (
2024-02-21 13:22:17 +00:00
json : strval ( file_get_contents ( $workingDir . '/composer.json' )),
2024-02-21 12:48:33 +00:00
associative : true ,
);
$dependencies = array_keys ( $json [ 'require' ]);
if ( in_array ( needle : 'drupal/core' , haystack : $dependencies , strict : true ) || in_array ( needle : 'drupal/core-recommended' , haystack : $dependencies , strict : true )) {
$projectType = ProjectType :: Drupal -> value ;
} elseif ( in_array ( needle : 'sculpin/sculpin' , haystack : $dependencies , strict : true )) {
$projectType = ProjectType :: Sculpin -> value ;
} elseif ( in_array ( needle : 'symfony/framework-bundle' , haystack : $dependencies , strict : true )) {
$projectType = ProjectType :: Symfony -> value ;
}
2024-02-22 00:31:29 +00:00
} elseif ( $filesystem -> exists ( $workingDir . '/fractal.config.js' )) {
$projectLanguage = ProjectLanguage :: JavaScript -> value ;
$projectType = ProjectType :: Fractal -> value ;
2024-02-21 12:48:33 +00:00
}
2024-02-22 00:31:29 +00:00
// Even if the project language or type is found automatically, still
// override it with the option value if there is one.
$projectLanguage = $input -> getOption ( 'language' ) ? ? $projectLanguage ;
2024-02-21 12:48:33 +00:00
$projectType = $input -> getOption ( 'type' ) ? ? $projectType ;
2024-02-21 13:22:17 +00:00
$isDockerCompose = $filesystem -> exists ( $workingDir . '/docker-compose.yaml' );
2024-02-21 12:48:33 +00:00
2024-02-22 00:31:29 +00:00
switch ( $projectLanguage ) {
case ProjectLanguage :: PHP -> value :
switch ( $projectType ) {
case ProjectType :: Drupal -> value :
if ( $isDockerCompose ) {
$process = Process :: create (
command : [ 'docker' , 'compose' , 'build' ],
extraArgs : $extraArgs ,
workingDir : $workingDir ,
);
$process -> run ();
}
break ;
case ProjectType :: Symfony -> value :
// TODO: run humbug/box if added to generate a phar?
throw new RuntimeException ( 'No build command set for Symfony projects.' );
case ProjectType :: Sculpin -> value :
$process = Process :: create (
command : [ './vendor/bin/sculpin' , 'generate' ],
extraArgs : $extraArgs ,
workingDir : $workingDir ,
);
$process -> run ();
break ;
}
2024-02-21 12:48:33 +00:00
2024-02-22 00:31:29 +00:00
case ProjectLanguage :: JavaScript -> value :
switch ( $projectType ) {
case ProjectType :: Fractal -> value :
$process = Process :: create (
command : [ 'npx' , 'fractal' , 'build' ],
extraArgs : $extraArgs ,
workingDir : $workingDir ,
);
$process -> run ();
break ;
2024-02-21 12:48:33 +00:00
}
break ;
}
return Command :: SUCCESS ;
}
}