2023-02-28 17:00:04 +00:00
< ? php
declare ( strict_types = 1 );
namespace Rector\Core\Console\Command ;
2023-03-01 13:00:30 +00:00
use RectorPrefix202303\Nette\Utils\FileSystem ;
use RectorPrefix202303\Nette\Utils\Strings ;
use RectorPrefix202303\OndraM\CiDetector\CiDetector ;
use RectorPrefix202303\Symfony\Component\Console\Command\Command ;
use RectorPrefix202303\Symfony\Component\Console\Input\InputInterface ;
use RectorPrefix202303\Symfony\Component\Console\Output\OutputInterface ;
use RectorPrefix202303\Symfony\Component\Console\Style\SymfonyStyle ;
use RectorPrefix202303\Symfony\Component\Process\Process ;
2023-02-28 17:00:04 +00:00
final class SetupCICommand extends Command
{
/**
* @ var string
* @ see https :// regex101 . com / r / etcmog / 1
*/
private const GITHUB_REPOSITORY_REGEX = '#github\\.com:(?<repository_name>.*?)\\.git#' ;
/**
* @ readonly
* @ var \Symfony\Component\Console\Style\SymfonyStyle
*/
private $symfonyStyle ;
public function __construct ( SymfonyStyle $symfonyStyle )
{
$this -> symfonyStyle = $symfonyStyle ;
parent :: __construct ();
}
protected function configure () : void
{
$this -> setName ( 'setup-ci' );
$this -> setDescription ( 'Add CI workflow to let Rector work for you' );
}
protected function execute ( InputInterface $input , OutputInterface $output ) : int
{
// detect current CI
$ci = $this -> resolveCurrentCI ();
if ( $ci === null ) {
$this -> symfonyStyle -> error ( 'No CI detected' );
return self :: FAILURE ;
}
2023-03-02 15:27:05 +00:00
if ( $ci !== CiDetector :: CI_GITHUB_ACTIONS ) {
$noteMessage = \sprintf ( 'Only Github Action is supported for now.%sCreate an issue to add your CI %s' , \PHP_EOL , 'https://github.com/rectorphp/rector/issues/' );
$this -> symfonyStyle -> note ( $noteMessage );
return self :: SUCCESS ;
}
$rectorWorkflowFilePath = \getcwd () . '/.github/workflows/rector.yaml' ;
if ( \file_exists ( $rectorWorkflowFilePath )) {
$response = $this -> symfonyStyle -> ask ( 'The "rector.yaml" workflow already exists. Overwrite it?' , 'Yes' );
if ( ! \in_array ( $response , [ 'y' , 'yes' , 'Yes' ], \true )) {
$this -> symfonyStyle -> note ( 'Nothing changed' );
2023-02-28 17:00:04 +00:00
return self :: SUCCESS ;
}
}
2023-03-02 15:27:05 +00:00
$currentRepository = $this -> resolveCurrentRepositoryName ( \getcwd ());
if ( $currentRepository === null ) {
$this -> symfonyStyle -> error ( 'Current repository name could not be resolved' );
return self :: FAILURE ;
}
$workflowTemplate = FileSystem :: read ( __DIR__ . '/../../../templates/rector-github-action-check.yaml' );
$workflowContents = \strtr ( $workflowTemplate , [ '__CURRENT_REPOSITORY__' => $currentRepository ]);
FileSystem :: write ( $rectorWorkflowFilePath , $workflowContents );
$this -> symfonyStyle -> newLine ();
$this -> symfonyStyle -> note ( 'The "rector.yaml" workflow was added' );
$this -> symfonyStyle -> newLine ();
$this -> symfonyStyle -> title ( '2 steps more to run you Github Action:' );
$this -> symfonyStyle -> writeln ( '1) Generate new Github Token here:' . \PHP_EOL . 'https://github.com/settings/tokens/new' );
$this -> symfonyStyle -> newLine ();
$this -> symfonyStyle -> writeln ( '2) Add it to your repository secrets under "GITHUB_TOKE" name:' . \PHP_EOL . \sprintf ( 'https://github.com/%s/settings/secrets/actions/new' , $currentRepository ));
$this -> symfonyStyle -> newLine ();
2023-02-28 17:00:04 +00:00
return Command :: SUCCESS ;
}
/**
* @ return CiDetector :: CI_ *| null
*/
private function resolveCurrentCI () : ? string
{
if ( \file_exists ( \getcwd () . '/.github' )) {
return CiDetector :: CI_GITHUB_ACTIONS ;
}
return null ;
}
private function resolveCurrentRepositoryName ( string $currentDirectory ) : ? string
{
// resolve current repository name
$process = new Process ([ 'git' , 'remote' , 'get-url' , 'origin' ], $currentDirectory , null , null , null );
$process -> run ();
$output = $process -> getOutput ();
$match = Strings :: match ( $output , self :: GITHUB_REPOSITORY_REGEX );
return $match [ 'repository_name' ] ? ? null ;
}
}