Skip to content

Commit

Permalink
Merge pull request #216 from woocommerce/24-10/overwrite-scaffolded
Browse files Browse the repository at this point in the history
Overwrite scaffolded tests with safety checks
  • Loading branch information
Luc45 authored Oct 11, 2024
2 parents 9290d57 + 9d7a91a commit 7eb5ad6
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 0 deletions.
Binary file modified qit
Binary file not shown.
122 changes: 122 additions & 0 deletions src/src/Commands/CustomTests/ScaffoldE2ECommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Filesystem\Filesystem;
use function QIT_CLI\normalize_path;

class ScaffoldE2ECommand extends Command {
Expand All @@ -27,6 +29,22 @@ protected function execute( InputInterface $input, OutputInterface $output ): in
if ( ! $this->getHelper( 'question' )->ask( $input, $output, new ConfirmationQuestion( "Directory already exists. Scaffold E2E tests in \"$path_to_generate\" anyway? <question>(y/n)</question> ", false ) ) ) {
return Command::SUCCESS;
}

try {
$this->safely_delete_scaffolded_directory( $path_to_generate );
} catch ( \Exception $e ) {
$io = new SymfonyStyle( $input, $output );

$io->warning( [
"Could not delete the existing directory: $path_to_generate",
$e->getMessage(),
] );

$output->writeln( '<comment>For safety reasons, only expected files are deleted.</comment>' );
$output->writeln( '<comment>Please delete the directory "' . $path_to_generate . '" manually and try again.</comment>' );

return Command::FAILURE;
}
}

if ( file_exists( $path_to_generate ) ) {
Expand Down Expand Up @@ -85,6 +103,110 @@ protected function execute( InputInterface $input, OutputInterface $output ): in
return Command::SUCCESS;
}

/**
* Safely deletes a scaffolded directory after performing safety checks.
*
* @param string $path_to_generate The path to the directory to be safely deleted.
*
* @throws \RuntimeException If the directory contains unexpected files or directories.
*/
protected function safely_delete_scaffolded_directory( string $path_to_generate ): void {
$expected_files = [
'./' => [
'*.spec.js',
],
'bootstrap' => [
'*.sh',
'*.php',
'*.js',
],
];

if ( ! is_dir( $path_to_generate ) ) {
throw new \RuntimeException( "$path_to_generate is not a directory" );
}

$root_iterator = new \DirectoryIterator( $path_to_generate );

$has_bootstrap_dir = false;

foreach ( $root_iterator as $fileinfo ) {
if ( $fileinfo->isDot() ) {
continue;
}

$filename = $fileinfo->getFilename();

if ( $fileinfo->isDir() ) {
if ( $filename === 'bootstrap' ) {
$has_bootstrap_dir = true;
} else {
throw new \RuntimeException( "Unexpected directory '$filename' found in the root directory." );
}
} elseif ( $fileinfo->isFile() ) {
// Check if the file matches any of the expected patterns in './'.
$matches_expected = false;
foreach ( $expected_files['./'] as $pattern ) {
if ( fnmatch( $pattern, $filename ) ) {
$matches_expected = true;
break;
}
}
if ( ! $matches_expected ) {
throw new \RuntimeException( "Unexpected file '$filename' found in the root directory." );
}
} else {
throw new \RuntimeException( "Unexpected item '$filename' found in the root directory." );
}
}

// If 'bootstrap' directory exists, check its contents.
if ( $has_bootstrap_dir ) {
$bootstrap_path = $path_to_generate . DIRECTORY_SEPARATOR . 'bootstrap';
if ( ! is_dir( $bootstrap_path ) ) {
throw new \RuntimeException( "'bootstrap' exists but is not a directory." );
}

$bootstrap_iterator = new \DirectoryIterator( $bootstrap_path );

// Iterate over bootstrap directory.
foreach ( $bootstrap_iterator as $fileinfo ) {
if ( $fileinfo->isDot() ) {
continue;
}

$filename = $fileinfo->getFilename();

if ( $fileinfo->isDir() ) {
throw new \RuntimeException( "Unexpected directory '$filename' found in the 'bootstrap' directory." );
} elseif ( $fileinfo->isFile() ) {
// Check if the file matches any of the expected patterns in 'bootstrap'.
$matches_expected = false;
foreach ( $expected_files['bootstrap'] as $pattern ) {
if ( fnmatch( $pattern, $filename ) ) {
$matches_expected = true;
break;
}
}
if ( ! $matches_expected ) {
throw new \RuntimeException( "Unexpected file '$filename' found in the 'bootstrap' directory." );
}
} else {
throw new \RuntimeException( "Unexpected item '$filename' found in the 'bootstrap' directory." );
}
}
}

// All safety checks passed, proceed to delete the directory.
$filesystem = new Filesystem();

try {
$filesystem->remove( $path_to_generate );
} catch ( \Exception $exception ) {
throw new \RuntimeException( "An error occurred while deleting '$path_to_generate': " . $exception->getMessage() );
}
}

protected function generate_bootstrap_shell_example(): string {
return <<<'SHELL'
#!/bin/bash
Expand Down

0 comments on commit 7eb5ad6

Please sign in to comment.