Skip to content

Commit e975c90

Browse files
committed
Inital commit
1 parent ab88f20 commit e975c90

File tree

4 files changed

+583
-0
lines changed

4 files changed

+583
-0
lines changed

class-phpcs-diff-cache.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
class PHPCS_Diff_Cache {
4+
5+
public function __construct() {
6+
7+
}
8+
9+
public function get( $cache_key, $cache_group ) {
10+
wp_cache_get( $cache_key, $cache_group );
11+
}
12+
13+
}

class-phpcs-diff-svn-parser.php

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
<?php
2+
3+
class PHPCS_Diff_SVN_parser {
4+
5+
// SVN credentials used for checking out individual revisions.
6+
private $svn_username = ''; // @todo: add your SVN username here
7+
private $svn_password = ''; // @todo: add your SVN password here
8+
9+
// Used to store details about the repo the class was initialized with.
10+
public $repo; // Specific repository - eg.: plugin's name.
11+
public $repo_url; // SVN repository URL.
12+
public $table; // Table used for storing information about revisions.
13+
14+
function __construct( $repo ) {
15+
16+
switch ( $repo ) {
17+
18+
case 'hello-dolly':
19+
$this->repo_url = 'https://plugins.svn.wordpress.org/';
20+
break;
21+
22+
# Add new repos here. See details at the top of this file.
23+
}
24+
25+
$this->repo = $repo;
26+
}
27+
28+
public function get_diff( $folder, $end_revision, $start_revision = null, $options = array() ) {
29+
$summarize = false;
30+
$xml = false;
31+
$ignore_space_change = false;
32+
33+
if ( isset( $options['summarize'] ) ) {
34+
$summarize = (bool) $options['summarize'];
35+
36+
// xml is only available in summaries
37+
if ( $summarize && isset( $options['xml'] ) ) {
38+
$xml = (bool) $options['xml'];
39+
}
40+
}
41+
42+
if ( isset( $options['ignore-space-change'] ) ) {
43+
$ignore_space_change = (bool) $options['ignore-space-change'];
44+
}
45+
46+
$end_revision = (int) $end_revision;
47+
$folder = str_replace( '..', '', $folder ); // Prevent moving up a directory
48+
49+
if ( $start_revision && is_numeric( $start_revision ) ) {
50+
$start_revision = (int) $start_revision;
51+
} else {
52+
// @todo is this really the best way to get the diff if there was no previous revision?
53+
$start_revision = 1;
54+
}
55+
56+
$repo_url = esc_url_raw( trailingslashit( $this->repo_url ) . trailingslashit( $this->repo ) . $folder );
57+
58+
$diff = shell_exec(
59+
sprintf( 'svn diff %s --non-interactive --no-auth-cache --username %s --password %s -r %d:%d %s %s %s',
60+
escapeshellarg( $repo_url ),
61+
escapeshellarg( $this->svn_username ),
62+
escapeshellarg( $this->svn_password ),
63+
(int) $start_revision,
64+
(int) $end_revision,
65+
( $summarize ? '--summarize' : '' ),
66+
( $xml ? '--xml' : '' ),
67+
( $ignore_space_change ? '-x -b' : '' )
68+
)
69+
);
70+
71+
return $diff;
72+
}
73+
74+
/**
75+
* Collect information about the diff
76+
*
77+
* @param string $diff_file full svn .diff file to be parsed for information
78+
*
79+
* @return array information about the diff
80+
*/
81+
public static function parse_diff_for_info( $diff_file ){
82+
83+
$files = preg_split( '/^Index: (.+)$/m', $diff_file, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
84+
85+
//result is a flat array with alternating 'filename', 'file_contents', 'filename', 'file_cotnents'... let's organize that into an associative array 'file_name'=>'file_contents'
86+
$diff_files = call_user_func_array( 'array_merge', array_map( function( $pair ) { return array( $pair[0] => $pair[1] ); }, array_chunk( $files, 2) ) );
87+
$results = array();
88+
$lines_added = $lines_removed = 0;
89+
90+
foreach ( $diff_files as $file_name => $file_diff ) {
91+
92+
//Remove property changes from the file_diff and store it in file_parts[1] if present
93+
$file_parts = preg_split( '/Property changes on: (?:.+)/', $file_diff, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
94+
$file_diff = $file_parts[0];
95+
unset( $file_parts );
96+
97+
$results[$file_name] = array( 'file_name' => $file_name, 'lines_added' => 0, 'lines_removed' => 0 );
98+
99+
$results[$file_name]['lines'] = array();
100+
101+
$diff_lines = explode( PHP_EOL, $file_diff );
102+
$old_start = $new_start = 0;
103+
foreach( $diff_lines as $line ) {
104+
switch( true ) {
105+
case preg_match( '/^No differences encountered/', $line ):
106+
case preg_match( '/^$/', $line ):
107+
break;
108+
case preg_match( '/^(\-\-\-|\+\+\+)/', $line ):
109+
if ( "--- {$file_name} (revision 0)" === trim( str_replace( "\t", ' ', $line ) ) ) {
110+
$results[$file_name]['is_new_file'] = true;
111+
}
112+
break;
113+
case preg_match( '/^@@ [-+]([0-9]+)*,([0-9]+)* [+-]([0-9]+)*,([0-9]+)* @@/', $line, $match ):
114+
$old_start = $match[1];
115+
$new_start = $match[3];
116+
break;
117+
case preg_match( '/^ (.*)/', $line, $match ):
118+
$results[$file_name]['lines'][] = array(
119+
'old_line_number' => $old_start,
120+
'new_line_number' => $new_start,
121+
'is_context' => true,
122+
// 'line' => $match[1], // Might be useful for debug.
123+
);
124+
$old_start++; $new_start++;
125+
break;
126+
case preg_match( '/^\+(.*)/', $line, $match ):
127+
$lines_added++;
128+
$results[$file_name]['lines_added']++;
129+
$results[$file_name]['lines'][] = array(
130+
'new_line_number' => $new_start,
131+
'is_added' => true,
132+
// 'line' => $match[1], // Might be useful for debug.
133+
);
134+
$new_start++;
135+
break;
136+
case preg_match( '/^\-(.*)/', $line, $match ):
137+
$lines_removed++;
138+
$results[$file_name]['lines_removed']++;
139+
$results[$file_name]['lines'][] = array(
140+
'old_line_number' => $old_start,
141+
'is_removed' => true,
142+
// 'line' => $match[1], // Might be useful for debug.
143+
);
144+
$old_start++;
145+
break;
146+
case preg_match( '/^diff -r/', $line ):
147+
break;
148+
}
149+
}
150+
151+
}
152+
$diff_info = array(
153+
'file_diffs' => $results,
154+
);
155+
156+
return $diff_info;
157+
158+
}
159+
160+
}

0 commit comments

Comments
 (0)