| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- <?php
- namespace Tools\Shell;
- use Cake\Console\Shell;
- use Cake\Filesystem\Folder;
- use Cake\Utility\Inflector;
- use Cake\Core\Plugin;
- /**
- * Shell to remove superfluous whitespace.
- *
- * @author Mark Scherer
- * @license MIT
- */
- class WhitespaceShell extends Shell {
- /**
- * Each report: [0] => found, [1] => corrected
- *
- * @var array
- */
- public $report = array(
- 'leading' => array(0, 0),
- 'trailing' => array(0, 0)
- );
- /**
- * Whitespaces before or after <?php and ?>.
- * The latter should be removed from PHP files by the way.
- *
- * @return void
- */
- public function clean() {
- if (!empty($this->args[0])) {
- $folder = realpath($this->args[0]);
- } elseif ($this->params['plugin']) {
- $folder = Plugin::path(Inflector::classify($this->params['plugin']));
- } else {
- $folder = APP;
- }
- $App = new Folder($folder);
- $this->out("Checking *.php in " . $folder);
- $files = $App->findRecursive('.*\.php');
- $this->out('Found ' . count($files) . ' files.');
- $action = $this->in('Continue? [y]/[n]', array('y', 'n'), 'n');
- if ($action !== 'y') {
- return $this->error('Aborted');
- }
- $folders = array();
- foreach ($files as $file) {
- $errors = array();
- $action = '';
- $this->out('Processing ' . $file, 1, Shell::VERBOSE);
- $c = file_get_contents($file);
- if (preg_match('/^[\n\r|\n|\r|\s]+\<\?php/', $c)) {
- $errors[] = 'leading';
- }
- if (preg_match('/\?\>[\n\r|\n|\r|\s]+$/', $c)) {
- $errors[] = 'trailing';
- }
- if (empty($errors)) {
- continue;
- }
- foreach ($errors as $e) {
- $this->report[$e][0]++;
- }
- $this->out('');
- $this->out('contains ' . implode(' and ' , $errors) . ' whitespaces: ' . $this->shortPath($file));
- $dirname = dirname($file);
- if (in_array($dirname, $folders)) {
- $action = 'y';
- }
- while (empty($action)) {
- $action = $this->in('Remove? [y]/[n], [a] for all in this folder, [r] for all below, [*] for all files(!), [q] to quit', array('y', 'n', 'r', 'a', 'q', '*'), 'q');
- }
- if ($action === '*') {
- $action = 'y';
- } elseif ($action === 'a') {
- $action = 'y';
- $folders[] = $dirname;
- $this->out('All: ' . $dirname);
- }
- if ($action === 'q') {
- return $this->error('Abort... Done');
- }
- if ($action === 'y') {
- if (in_array('leading', $errors)) {
- $c = preg_replace('/^\s+\<\?php/', '<?php', $c);
- }
- if (in_array('trailing', $errors)) {
- $c = preg_replace('/\?\>\s+$/', '?>', $c);
- }
- file_put_contents($file, $c);
- foreach ($errors as $e) {
- $this->report[$e][1]++;
- }
- $this->out('fixed ' . implode(' and ' , $errors) . ' whitespaces: ' . $this->shortPath($file));
- }
- }
- // Report.
- $this->out('--------');
- $this->out('found ' . $this->report['leading'][0] . ' leading, ' . $this->report['trailing'][0] . ' trailing ws');
- $this->out('fixed ' . $this->report['leading'][1] . ' leading, ' . $this->report['trailing'][1] . ' trailing ws');
- }
- /**
- * Whitespaces at the end of the file
- *
- * @return void
- */
- public function eof() {
- if (!empty($this->args[0])) {
- $folder = realpath($this->args[0]);
- } else {
- $folder = APP;
- }
- $App = new Folder($folder);
- $this->out("Checking *.php in " . $folder);
- $files = $App->findRecursive('.*\.php');
- $this->out('Found ' . count($files) . ' files.');
- $action = $this->in('Continue? [y]/[n]', array('y', 'n'), 'n');
- if ($action !== 'y') {
- return $this->error('Aborted');
- }
- foreach ($files as $file) {
- $this->out('Processing ' . $file, 1, Shell::VERBOSE);
- $content = $store = file_get_contents($file);
- $newline = PHP_EOL;
- $x = substr_count($content, "\r\n");
- if ($x > 0) {
- $newline = "\r\n";
- } else {
- $newline = "\n";
- }
- // add one new line at the end
- $content = trim($content) . $newline;
- if ($content !== $store) {
- file_put_contents($file, $content);
- }
- }
- $this->out('Done');
- }
- public function getOptionParser() {
- $subcommandParser = array(
- 'options' => array(
- 'ext' => array(
- 'short' => 'e',
- 'help' => 'Specify extensions [php|txt|...]',
- 'default' => '',
- ),
- 'dry-run' => array(
- 'short' => 'd',
- 'help' => 'Dry run the clear command, no files will actually be deleted. Should be combined with verbose!',
- 'boolean' => true
- ),
- 'plugin' => array(
- 'short' => 'p',
- 'help' => 'Plugin',
- 'default' => '',
- ),
- )
- );
- return parent::getOptionParser()
- ->description('The Whitespace Shell removes uncessary/wrong whitespaces.
- Either provide a path as first argument, use -p PluginName or run it as it is for the complete APP dir.')
- ->addSubcommand('clean', array(
- 'help' => 'Detect and remove any leading/trailing whitespaces',
- 'parser' => $subcommandParser
- ))
- ->addSubcommand('eof', array(
- 'help' => 'Fix whitespace issues at the end of PHP files (a single newline as per coding standards)',
- 'parser' => $subcommandParser
- ));
- }
- }
|