Writing Command Line Applications – Tips & Tricks – dry-run

Testing command line applications is not easy. Dry Run, is a testing process usually used for command line applications. Also it allows you to simulate what will happen when you run the command.

It’s kinda like running SELECT statement on SQL before running DELETE/UPDATE statements and see which records will be affected.

I’m going to share an example use case. Assume that you have a command which deletes unused files from your S3 bucket.

<?php

$files = File::all();

$this->output->writeln('There are '.count($files).' file to be checked');

foreach ($files as $file) {
    if (!$this->fileService->isFileInUse($file)) {
        $this->fileService->deleteFile($file);
        $this->output->writeln('File has been deleted from storage: file_id_'.$file->id);
    }
}

This command is a bit risky! If there is an unexpected behavior on isFileInUse method, then we can delete wrong files. I prefer to simulate data before actually running these kind of commands.

So --dry-run option is with us!

<?php

// In Laravel, we use `option` method to get an option.
$dryRun = $this->option('dry-run');

$files = File::all();

$this->output->writeln('There are '.count($files).' file to be checked');

foreach ($files as $file) {
    if (!$this->fileService->isFileInUse($file)) {
        if ($dryRun) {
            $this->output->writeln('File will be deleted from storage: file_id_'.$file->id. ' URL: '.$file->url);
            continue;
        }

        $this->fileService->deleteFile($file);
        $this->output->writeln('File has been deleted from storage: file_id_'.$file->id);
    }
}
php artisan s3:delete-unused-files --dry-run

Simple! We’re just passing --dry-run option to command line and it’s telling us which files will be deleted. In the example, I’ve also added the url to output. You can add whatever you want to make spot-check. If everything seems good, you can run actual command without dry-run.

Leave a Reply

Your email address will not be published. Required fields are marked *