Skip to content

Commit 79c279e

Browse files
committed
Add latest changes
1 parent b586dce commit 79c279e

File tree

4 files changed

+208
-81
lines changed

4 files changed

+208
-81
lines changed

.maintenance/src/Contrib_List_Command.php

Lines changed: 150 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,15 @@ final class Contrib_List_Command {
1212
*
1313
* ## OPTIONS
1414
*
15+
* [<repo>]
16+
* : Name of the repository to fetch the release notes for. If no user/org
17+
* was provided, 'wp-cli' org is assumed. If no repo is passed, release
18+
* notes for the entire org state since the last bundle release are fetched.
19+
*
20+
* [<milestone>...]
21+
* : Name of one or more milestones to fetch the release notes for. If none
22+
* are passed, the current open one is assumed.
23+
*
1524
* [--format=<format>]
1625
* : Render output in a specific format.
1726
* ---
@@ -23,95 +32,157 @@ final class Contrib_List_Command {
2332
*
2433
* @when before_wp_load
2534
*/
26-
public function __invoke( $_, $assoc_args ) {
35+
public function __invoke( $args, $assoc_args ) {
36+
37+
$repos = null;
38+
$milestone_names = null;
39+
$use_bundle = false;
40+
41+
if ( count( $args ) > 0 ) {
42+
$repos = [ array_shift( $args ) ];
43+
}
44+
45+
$milestone_names = $args;
46+
47+
if ( empty( $repos ) ) {
48+
$use_bundle = true;
49+
$repos = [
50+
'wp-cli/wp-cli-bundle',
51+
'wp-cli/wp-cli',
52+
'wp-cli/handbook',
53+
'wp-cli/wp-cli.github.com'
54+
];
55+
}
2756

2857
$contributors = array();
2958
$pull_request_count = 0;
3059

3160
// Get the contributors to the current open large project milestones
32-
foreach( array( 'wp-cli/wp-cli-bundle', 'wp-cli/wp-cli', 'wp-cli/handbook', 'wp-cli/wp-cli.github.com' ) as $repo ) {
33-
$milestones = GitHub::get_project_milestones( $repo );
34-
// Cheap way to get the latest milestone
35-
$milestone = array_shift( $milestones );
36-
if ( ! $milestone ) {
37-
continue;
38-
}
39-
WP_CLI::log( 'Current open ' . $repo . ' milestone: ' . $milestone->title );
40-
$pull_requests = GitHub::get_project_milestone_pull_requests( $repo, $milestone->number );
41-
$repo_contributors = GitHub::parse_contributors_from_pull_requests( $pull_requests );
42-
WP_CLI::log( ' - Contributors: ' . count( $repo_contributors ) );
43-
WP_CLI::log( ' - Pull requests: ' . count( $pull_requests ) );
44-
$pull_request_count += count( $pull_requests );
45-
$contributors = array_merge( $contributors, $repo_contributors );
46-
}
61+
foreach( $repos as $repo ) {
62+
if ( $milestone_names ) {
63+
$milestone_names = (array) $milestone_names;
4764

48-
// Identify all command dependencies and their contributors
65+
$potential_milestones = GitHub::get_project_milestones(
66+
$repo,
67+
array( 'state' => 'all' )
68+
);
4969

50-
$bundle = 'wp-cli/wp-cli-bundle';
70+
$milestones = array();
71+
foreach ( $potential_milestones as $potential_milestone ) {
72+
if ( in_array(
73+
$potential_milestone->title,
74+
$milestone_names,
75+
true
76+
) ) {
77+
$milestones[] = $potential_milestone;
78+
$index = array_search(
79+
$potential_milestone->title,
80+
$milestone_names,
81+
true
82+
);
83+
unset( $milestone_names[ $index ] );
84+
}
85+
}
5186

52-
$milestones = GitHub::get_project_milestones( $bundle, array( 'state' => 'closed' ) );
53-
$milestone = array_reduce(
54-
$milestones,
55-
function ( $tag, $milestone ) {
56-
return version_compare( $milestone->title, $tag, '>' ) ? $milestone->title : $tag;
57-
}
58-
);
59-
$tag = ! empty( $milestone ) ? "v{$milestone}" : 'master';
60-
61-
$composer_lock_url = sprintf( 'https://raw.githubusercontent.com/%s/%s/composer.lock', $bundle, $tag );
62-
WP_CLI::log( 'Fetching ' . $composer_lock_url );
63-
$response = Utils\http_request( 'GET', $composer_lock_url );
64-
if ( 200 !== $response->status_code ) {
65-
WP_CLI::error( sprintf( 'Could not fetch composer.json (HTTP code %d)', $response->status_code ) );
66-
}
67-
$composer_json = json_decode( $response->body, true );
68-
69-
// TODO: Only need for initial v2.
70-
$composer_json['packages'][] = array( 'name' => 'wp-cli/i18n-command', 'version' => 'v2' );
71-
usort( $composer_json['packages'], function ( $a, $b ) {
72-
return $a['name'] < $b['name'] ? -1 : 1;
73-
} );
74-
75-
foreach( $composer_json['packages'] as $package ) {
76-
$package_name = $package['name'];
77-
$version_constraint = str_replace( 'v', '', $package['version'] );
78-
if ( ! preg_match( '#^wp-cli/.+-command$#', $package_name )
79-
&& ! in_array( $package_name, array(
80-
'wp-cli/wp-cli-tests',
81-
'wp-cli/regenerate-readme',
82-
'wp-cli/autoload-splitter',
83-
'wp-cli/wp-config-transformer',
84-
'wp-cli/php-cli-tools',
85-
'wp-cli/spyc',
86-
), true ) ) {
87-
continue;
88-
}
89-
// Closed milestones denote a tagged release
90-
$milestones = GitHub::get_project_milestones( $package_name, array( 'state' => 'closed' ) );
91-
$milestone_ids = array();
92-
$milestone_titles = array();
93-
foreach( $milestones as $milestone ) {
94-
if ( ! version_compare( $milestone->title, $version_constraint, '>' ) ) {
95-
continue;
96-
}
97-
$milestone_ids[] = $milestone->number;
98-
$milestone_titles[] = $milestone->title;
99-
}
100-
// No shipped releases for this milestone.
101-
if ( empty( $milestone_ids ) ) {
102-
continue;
103-
}
104-
WP_CLI::log( 'Closed ' . $package_name . ' milestone(s): ' . implode( ', ', $milestone_titles ) );
105-
foreach( $milestone_ids as $milestone_id ) {
106-
$pull_requests = GitHub::get_project_milestone_pull_requests( $package_name, $milestone_id );
107-
$repo_contributors = GitHub::parse_contributors_from_pull_requests( $pull_requests );
108-
WP_CLI::log( ' - Contributors: ' . count( $repo_contributors ) );
109-
WP_CLI::log( ' - Pull requests: ' . count( $pull_requests ) );
110-
$pull_request_count += count( $pull_requests );
111-
$contributors = array_merge( $contributors, $repo_contributors );
112-
}
87+
if ( ! empty( $milestone_names ) ) {
88+
WP_CLI::warning(
89+
sprintf(
90+
"Couldn't find the requested milestone(s) '%s' in repository '%s'.",
91+
implode( "', '", $milestone_names ),
92+
$repo
93+
)
94+
);
95+
}
96+
} else {
97+
$milestones = GitHub::get_project_milestones( $repo );
98+
// Cheap way to get the latest milestone
99+
$milestone = array_shift( $milestones );
100+
if ( ! $milestone ) {
101+
continue;
102+
}
103+
}
104+
$entries = array();
105+
foreach ( $milestones as $milestone ) {
106+
WP_CLI::debug("Using milestone '{$milestone->title}' for repo '{$repo}'", 'release-notes');
107+
WP_CLI::log('Current open ' . $repo . ' milestone: ' . $milestone->title);
108+
$pull_requests = GitHub::get_project_milestone_pull_requests($repo, $milestone->number);
109+
$repo_contributors = GitHub::parse_contributors_from_pull_requests($pull_requests);
110+
WP_CLI::log(' - Contributors: ' . count($repo_contributors));
111+
WP_CLI::log(' - Pull requests: ' . count($pull_requests));
112+
$pull_request_count += count($pull_requests);
113+
$contributors = array_merge($contributors, $repo_contributors);
114+
}
113115
}
114116

117+
if ( $use_bundle ) {
118+
// Identify all command dependencies and their contributors
119+
120+
$bundle = 'wp-cli/wp-cli-bundle';
121+
122+
$milestones = GitHub::get_project_milestones( $bundle, array( 'state' => 'closed' ) );
123+
$milestone = array_reduce(
124+
$milestones,
125+
function ( $tag, $milestone ) {
126+
return version_compare( $milestone->title, $tag, '>' ) ? $milestone->title : $tag;
127+
}
128+
);
129+
$tag = ! empty( $milestone ) ? "v{$milestone}" : 'master';
130+
131+
$composer_lock_url = sprintf( 'https://raw.githubusercontent.com/%s/%s/composer.lock', $bundle, $tag );
132+
WP_CLI::log( 'Fetching ' . $composer_lock_url );
133+
$response = Utils\http_request( 'GET', $composer_lock_url );
134+
if ( 200 !== $response->status_code ) {
135+
WP_CLI::error( sprintf( 'Could not fetch composer.json (HTTP code %d)', $response->status_code ) );
136+
}
137+
$composer_json = json_decode( $response->body, true );
138+
139+
// TODO: Only need for initial v2.
140+
$composer_json['packages'][] = array( 'name' => 'wp-cli/i18n-command', 'version' => 'v2' );
141+
usort( $composer_json['packages'], function ( $a, $b ) {
142+
return $a['name'] < $b['name'] ? -1 : 1;
143+
} );
144+
145+
foreach( $composer_json['packages'] as $package ) {
146+
$package_name = $package['name'];
147+
$version_constraint = str_replace( 'v', '', $package['version'] );
148+
if ( ! preg_match( '#^wp-cli/.+-command$#', $package_name )
149+
&& ! in_array( $package_name, array(
150+
'wp-cli/wp-cli-tests',
151+
'wp-cli/regenerate-readme',
152+
'wp-cli/autoload-splitter',
153+
'wp-cli/wp-config-transformer',
154+
'wp-cli/php-cli-tools',
155+
'wp-cli/spyc',
156+
), true ) ) {
157+
continue;
158+
}
159+
// Closed milestones denote a tagged release
160+
$milestones = GitHub::get_project_milestones( $package_name, array( 'state' => 'closed' ) );
161+
$milestone_ids = array();
162+
$milestone_titles = array();
163+
foreach( $milestones as $milestone ) {
164+
if ( ! version_compare( $milestone->title, $version_constraint, '>' ) ) {
165+
continue;
166+
}
167+
$milestone_ids[] = $milestone->number;
168+
$milestone_titles[] = $milestone->title;
169+
}
170+
// No shipped releases for this milestone.
171+
if ( empty( $milestone_ids ) ) {
172+
continue;
173+
}
174+
WP_CLI::log( 'Closed ' . $package_name . ' milestone(s): ' . implode( ', ', $milestone_titles ) );
175+
foreach( $milestone_ids as $milestone_id ) {
176+
$pull_requests = GitHub::get_project_milestone_pull_requests( $package_name, $milestone_id );
177+
$repo_contributors = GitHub::parse_contributors_from_pull_requests( $pull_requests );
178+
WP_CLI::log( ' - Contributors: ' . count( $repo_contributors ) );
179+
WP_CLI::log( ' - Pull requests: ' . count( $pull_requests ) );
180+
$pull_request_count += count( $pull_requests );
181+
$contributors = array_merge( $contributors, $repo_contributors );
182+
}
183+
}
184+
}
185+
115186
WP_CLI::log( 'Total contributors: ' . count( $contributors ) );
116187
WP_CLI::log( 'Total pull requests: ' . $pull_request_count );
117188

.maintenance/src/GitHub.php

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,12 +272,14 @@ public static function delete_label(
272272
*
273273
* @param string $project
274274
* @param integer $milestone_id
275+
* @param bool $only_merged
275276
*
276277
* @return array
277278
*/
278279
public static function get_project_milestone_pull_requests(
279280
$project,
280-
$milestone_id
281+
$milestone_id,
282+
$only_merged = true
281283
) {
282284
$request_url = sprintf(
283285
self::API_ROOT . 'repos/%s/issues',
@@ -295,7 +297,11 @@ public static function get_project_milestone_pull_requests(
295297
list( $body, $headers ) = self::request( $request_url, $args );
296298
foreach ( $body as $issue ) {
297299
if ( ! empty( $issue->pull_request ) ) {
298-
$pull_requests[] = $issue;
300+
//if ( ! $only_merged || self::was_pull_request_merged( $project, $issue->number ) ) {
301+
$pull_requests[] = $issue;
302+
//} else {
303+
//WP_CLI::warning( "Skipping PR {$issue->number} ({$issue->title}), as it was not merged." );
304+
//}
299305
}
300306
}
301307
$args = array();
@@ -316,6 +322,26 @@ public static function get_project_milestone_pull_requests(
316322
return $pull_requests;
317323
}
318324

325+
/**
326+
* Check whether a specific pull request was actually merged.
327+
*
328+
* @param $project
329+
* @param $pull_request_number
330+
* @return bool
331+
*/
332+
public static function was_pull_request_merged( $project, $pull_request_number )
333+
{
334+
$request_url = sprintf(
335+
self::API_ROOT . 'repos/%s/pulls/%s',
336+
$project,
337+
$pull_request_number
338+
);
339+
340+
list( $body, $headers ) = self::request( $request_url );
341+
342+
return ! empty( $body->merged_at );
343+
}
344+
319345
/**
320346
* Parses the contributors from pull request objects.
321347
*

fetch-org

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env bash
2+
3+
REPOLIST=$(curl --silent https://api.github.com/orgs/wp-cli/repos\?per_page=100 -q | jq '.[].name')
4+
5+
for NAME in $REPOLIST; do
6+
REPO=$(echo $NAME | tr -d '"')
7+
if [ ! -d "$REPO" ]; then
8+
git clone "https://github.com/wp-cli/$REPO"
9+
fi
10+
done

foreach-bundle

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
3+
BUNDLE_DEPENDENCIES=$(curl --silent https://raw.githubusercontent.com/wp-cli/wp-cli-bundle/master/composer.json -q | jq '.["require"] | keys[]' )
4+
BUNDLE_DEPENDENCIES=$(echo "wp-cli/wp-cli-bundle $BUNDLE_DEPENDENCIES")
5+
6+
for NAME in $BUNDLE_DEPENDENCIES; do
7+
8+
REPO=$(echo $NAME | tr -d '"')
9+
case $REPO in wp-cli/*)
10+
export REPO=$(echo "$REPO" | sed -e "s|^wp-cli/||")
11+
if [ -d "$REPO" ]; then
12+
OLDPWD="$(pwd)"
13+
cd "$REPO"
14+
echo "--- $REPO : ---"
15+
"$@"
16+
cd "$OLDPWD"
17+
fi
18+
esac
19+
done
20+

0 commit comments

Comments
 (0)