Skip to content

Commit 89b55c5

Browse files
committed
Implement the support for inspecting unstaged changes via --sniff_unstaged.
1 parent 47631f6 commit 89b55c5

File tree

4 files changed

+51
-13
lines changed

4 files changed

+51
-13
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Options:
3232
- `--standard[=<arg>]`: Name of the phpcs standard to use: 'WordPress', 'WordPress-VIP', 'WordPress-Core', 'WordPress-Docs', 'WordPress-Extra', 'Toolset'
3333
- `--log_level[=<arg>]`: Control verbosity by passing a number from 0 (most verbose) to 2 (least verbose, only errors).
3434
- `--ignore_space_changes`: Whitespace changes will be ignored when git is used to produce the diff.
35+
- `--sniff_unstaged`: Inspect unstaged changes in the working directory against the latest commit (HEAD). `--start_revision` and `--end_revision` will be ignored in this case.
3536

3637
Limitations:
3738

bin/phpcs-diff

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ $getopt = new \GetOpt\GetOpt(
3939
[ 't', 'tolerance' ],
4040
[ 'standard' ],
4141
[ 'log_level' ],
42-
[ 'ignore_space_changes' ]
42+
[ 'ignore_space_changes', \GetOpt\GetOpt::NO_ARGUMENT ],
43+
[ 'sniff_unstaged', \GetOpt\GetOpt::NO_ARGUMENT ],
4344
]
4445
);
4546

@@ -62,9 +63,6 @@ $getopt->getOption( 'log_level', true )
6263
->setValidation( 'is_numeric' )
6364
->setDefaultValue( LoggerInterface::WARNING );
6465

65-
$getopt->getOption( 'ignore_space_changes', true )
66-
->setMode( \GetOpt\GetOpt::NO_ARGUMENT );
67-
6866
try {
6967
$getopt->process();
7068
} catch ( \GetOpt\ArgumentException $exception ) {
@@ -79,6 +77,12 @@ $phpcs_standard = $getopt->getOption( 'standard' );
7977
$log_level = $getopt->getOption( 'log_level' );
8078
$ignore_space_changes = $getopt->offsetExists( 'ignore_space_changes' );
8179

80+
$sniff_unstaged = $getopt->offsetExists( 'sniff_unstaged' );
81+
if( $sniff_unstaged ) {
82+
$start_revision = 'HEAD';
83+
$end_revision = Backends\Git::UNSTAGED;
84+
}
85+
8286
$logger = new Log\ShellLogger( (int) $log_level );
8387
$options = [ 'ignore-space-change' => $ignore_space_changes ];
8488
$version_control = new Backends\Git( '', $logger, $options );

inc/backends/Git.php

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class Git implements BackendInterface {
2323
/** @var string This is how the unified diff annotates files that didn't exist at a particular revision. */
2424
const DEV_NULL = '/dev/null';
2525

26+
/** @var string Represents unstaged changes in the working directory. */
27+
const UNSTAGED = '*UNSTAGED*';
28+
2629
/** @var LoggerInterface */
2730
private $log;
2831

@@ -68,11 +71,15 @@ public function get_diff( $directory, $end_commit, $start_commit = null, $option
6871
$arg_ignore_whitespace = '';
6972
}
7073

74+
if( self::UNSTAGED === $end_commit ) {
75+
return $this->get_diff_for_unstaged_changes( "$arg_git_dir $arg_ignore_whitespace", $start_commit );
76+
}
77+
7178
// Check if we're comparing the the same commit and show a message about it.
7279
//
7380
// We need to use git rev-parse in case a branch name or HEAD are provided.
74-
$start_commit_hash = shell_exec( "git $arg_git_dir rev-parse $start_commit" );
75-
$end_commit_hash = shell_exec( "git $arg_git_dir rev-parse $end_commit" );
81+
$start_commit_hash = trim( shell_exec( "git $arg_git_dir rev-parse $start_commit" ) );
82+
$end_commit_hash = trim( shell_exec( "git $arg_git_dir rev-parse $end_commit" ) );
7683
if( $start_commit_hash === $end_commit_hash ) {
7784
$this->log->log( LoggerInterface::ERROR, "Attempting to compare a commit $start_commit_hash with itself. Expect an empty result." );
7885
}
@@ -91,6 +98,24 @@ public function get_diff( $directory, $end_commit, $start_commit = null, $option
9198
return $diff;
9299
}
93100

101+
102+
/**
103+
* Get a diff between a selected commit and unstaged changes.
104+
*
105+
* @param string $git_args
106+
* @param string $start_commit Revision number to diff against.
107+
*
108+
* @return string
109+
*/
110+
private function get_diff_for_unstaged_changes( $git_args, $start_commit ) {
111+
$command = "git diff --unified=0 $git_args $start_commit";
112+
113+
$this->log->log( LoggerInterface::INFO, 'Generating a diff between unstaged changes and the selected commit: ' . $command );
114+
115+
$diff = shell_exec( $command );
116+
return $diff;
117+
}
118+
94119
/**
95120
* Collect information about the diff.
96121
*
@@ -152,11 +177,17 @@ public function run_phpcs_for_file_at_revision( $filename, $revision, $phpcs_com
152177
$filename, $revision
153178
) );
154179

155-
$git_command = sprintf(
156-
'git show --format=raw %s:%s',
157-
$revision,
158-
ltrim( $filename, '/' )
159-
);
180+
if( self::UNSTAGED === $revision ) {
181+
// Inspecting an unstaged file - just take it from the filesystem directly.
182+
$get_file_command = 'cat ' . ltrim( $filename, '/' );
183+
} else {
184+
// Get the content of the file at a particular commit.
185+
$get_file_command = sprintf(
186+
'git show --format=raw %s:%s',
187+
$revision,
188+
ltrim( $filename, '/' )
189+
);
190+
}
160191

161192
$phpcs_command = sprintf(
162193
'%s --report=json --runtime-set installed_paths %s --standard=%s --stdin-path=%s -',
@@ -166,7 +197,7 @@ public function run_phpcs_for_file_at_revision( $filename, $revision, $phpcs_com
166197
escapeshellarg( $filename )
167198
);
168199

169-
$command_string = "$git_command | $phpcs_command";
200+
$command_string = "$get_file_command | $phpcs_command";
170201

171202
return shell_exec( $command_string );
172203
}

inc/log/ShellLogger.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@ public function log( $severity, $message ) {
2626

2727
switch( $severity ) {
2828
case LoggerInterface::ERROR:
29+
file_put_contents('php://stderr', 'ERROR: ' .$message . PHP_EOL );
30+
break;
2931
case LoggerInterface::WARNING:
30-
file_put_contents('php://stderr', $message . PHP_EOL );
32+
file_put_contents('php://stderr', 'WARNING: ' .$message . PHP_EOL );
3133
break;
3234
default:
3335
file_put_contents('php://stdout', $message . PHP_EOL );

0 commit comments

Comments
 (0)