Task description
We have a really handy script at http://drupalcode.org/viewvc/drupal/contributions/tricks/cvs-release-notes/ that allows us to enter two tags and generate output akin to http://drupal.org/node/995778, like so:

 ./cvs-release-notes.php DRUPAL-6-0 DRUPAL-6-20 > ~/diff.html

This task is to port the cvs-release-notes.php script to Git, so it reads its log information out of git.drupal.org and uses Git commands to find it instead.

Deliverable
A git-release-notes.php script which can be run as follows:

./git-release-notes.php 6.0 6.20 > ~/diff.html

Extra bonus points for creating this as a Drush extension instead of a separate script.

Resources

Primary contact
Angela Byron (webchick)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

webchick’s picture

Status: Active » Needs review
Josh The Geek’s picture

Assigned: Unassigned » Josh The Geek
Status: Needs review » Active

This shouldn't be too hard. I'll do this.

Josh The Geek’s picture

Josh The Geek’s picture

Status: Active » Needs review

This needs testing. Please test the 6.x-1.0 tag, in master, I'll be working on some of the TODOs. Should I create a project node for this?

Josh The Geek’s picture

Project: Google Code-in » The Great Git Migration
Component: Code » Migration scripts

Sorry, I didn't notice that this was for Google code in until I was done. I was looking for something to do for git low hanging fruit. I moved this to the Great Git Migration, but what component should it be? I put it under migration scripts.

Josh The Geek’s picture

New version with bug fixes: 6.x-1.1 . This isn't a Drush extension, but that will come later.

Josh The Geek’s picture

I have tested this on a clone of the Views repo. It worked fine. The script takes a while to run, especially with a large number of commits between the tags. That's because the script uses PHP cURL to get the page data for every issue mentioned, to get the category. (It uses that to sort the output by category.) The latest version is 6.x-1.3 . I am starting branch 'drush' to try to make this Drush compatible.

marvil07’s picture

AFAIK cvs version of this script is just printing a simple <a href="http://drupal.org/node/$nid">#$nid</a> since it assumes the log have enough information.

PS: Maybe I am missing something since I did not reviewed the code, but just wanted to point that.

moshe weitzman’s picture

I'd love to put this command into devel.drush.inc. Seems like the best place to me. I'll do that as soon as folks think this is ready.

Josh The Geek’s picture

@marvil07: I updated that. It sorts the commits by issue type if it has one, otherwise it gets sorted into 'Other'. It uses PHP cURL to get the issue page data and pull it apart to get the type. (I finished all of the todos from the CVS version while working on this.)

@moshe weitzman: That would be cool! After this gets reviewed, I'll update the namespace.

@Everyone: What should the command be? I started with grn-generate (grn is git release notes), but recently I changed it to generate-notes.

Josh The Geek’s picture

@moshe weitzman: On a different branch.

webchick’s picture

Just in case we ever decide to move to Visual Source Safe (heehee), I'd make the command something about just generically 'release notes'. Maybe "release-notes-generate" or "drush rn"?

But definitely listen to more of a Drushy person's opinion on this than mine. :D

Josh The Geek’s picture

Updated to be release-notes, alias rn, at branch drush commit 2d0a080.

eliza411’s picture

Issue tags: +git sprint 9

Tagging for Git Sprint 9

Josh The Geek’s picture

In GitHub, master is 6.x-1.x, and drush is 6.x-2.x. I added a 6.x-2.0 tag.

Josh The Geek’s picture

Note: Drush command is based on the example command from Drush 3.1. I realize that 4.0 came out, and I need to update my Drush locally. After I do that, I'll update the command for Drush 4.x.
@moshe: Are there any good resources about updating 3.x Drush commands?

Josh The Geek’s picture

Please focus on drush. The lone php script will not be updated (not supported)

sdboyer’s picture

Really handy, but not actually critical for launch, so retagging appropriately.

I don't have time to test this personally, but putting it into drush seems like a great path forward. I'd be extra-super-mondo +1 to that. But I'll leave that up to y'all.

Josh The Geek’s picture

Drush script works. 6.x-2.1

webchick’s picture

Status: Needs review » Needs work
Issue tags: -git phase 2 +git phase 3, +git phase 2 leftovers

Finally getting around to testing this tonight. Thanks for your hard work!

This script doesn't seem to work atm though (else I'm doing something wrong).

What I did:

0. Downloaded the master branch of https://github.com/JoshTheGeek/git-release-notes as a .tar.gz and extracted it.
1. Copied the drush.grn.inc file to ~/.drush/grn/drush.grn.inc
2. Changed into the root directory of a git clone of core.
2. Entered drush rn 6.0 7.0

I get this:

<p>Changes since 6.0:</p>
<ul>
<li>Other changes:<ul>
<li>%B</li>
<li>%B</li>
<li>%B</li>
<li>%B</li>
...
</li>
</ul></li>
</ul>
webchick’s picture

Status: Needs work » Needs review

D'oh. :\ I guess this is because I had an older version of Git (1.7.1), because eojthebrave had 1.7.3 and it worked fine for him, and I just grabbed 1.7.4 and now it's working fine too. Huh.

Back to needs review then. ;)

webchick’s picture

Status: Needs review » Needs work

Ok. So some feedback:

1. When it's working on a project with very basic commits (like update_notifications_disable), it does this:

drush rn 6.x-1.0 
<p>Changes since 6.x-1.0:</p>
<ul>
<li>Other changes:<ul>
<li>Final adjustments before fulfilling #D7CX pledge.</li>
<li>Upgrading update status notifications to D7. Two whole lines of code. I'm shocked and disappointed.</li>
</ul></li>
</ul>

vs. cvs-release-notes.php:

./cvs-release-notes.php DRUPAL-6--1-0 DRUPAL-7--1-0
<p>Changes since DRUPAL-6--1-0:</p>
<ul>
<li>Adding a module to disable notifications about update status module being missing in 6.x core.</li>
<li>Fixing core compatibility string; updating README with installation instructions.</li>
<li>Minor wording change to description.</li>
<li>Adding installation instructions.</li>
</ul>

It's not clear to me why this is getting wrapped in a sub-list called "Other changes" as opposed to being at the top level. This looks like a bug.

Then, when you attempt to do this on a project with #xxx format commits (such as drupal), you get a bunch of this:

Wrong parameter count for strstr() grn.drush.inc:165                                        [warning]
Wrong parameter count for strstr() grn.drush.inc:165                                        [warning]
Wrong parameter count for strstr() grn.drush.inc:165                                        [warning]
Wrong parameter count for strstr() grn.drush.inc:165                                        [warning]

This is getting thrown from _drush_grn_get_page_data, which is this line here:

 <tr class="odd"><td>Priority:</td><td>',true); // And filter it to get the count

Looking at the rest of the function more closely, uh.... Dude.

function _drush_grn_get_page_data($issue) {
  $raw = file_get_contents("http://drupal.org/node/" . $issue);
  // Get type
  $init = strstr($raw, '  <div class="node-content">
    <div class="project-issue"><div id="project-summary-container" class="clear-block"><div id="project-issue-summary-table" class="summary"><table>
');
  $tfront = strstr($init,'<tr class="even"><td>Category:</td><td>'); // Find what's after the start tag
  $type = strstr($tfront,'</td> </tr>
 <tr class="odd"><td>Priority:</td><td>',true); // And filter it to get the count
  return $type;
}

You are doing a GET request against Drupal.org for *each* commit message?!?!? Noooooo! :)

I see that the reason you're doing this is to segment things out into bug fixes vs. features but this is no recommended standard that I know of, and furthermore it's *highly* uncool to slam Drupal.org like that from every single person's computer. Let's please revert back to cvs-release-notes.php behaviour, and make this script simply a pretty formatter around git log.

eojthebrave’s picture

Status: Needs work » Needs review
FileSize
4.56 KB

Oh man, this is awesome! It's working well in my tests but there were a couple of things that needed cleaning up.

I made a couple of changes including:

Cleaning up some coding standards and general formatting and renaming a couple of variables so that their use is clearer.

I also change the name of _drush_grn_print_changes to _drush_grn_format_changes because I think it better reflects what the function is doing.

Attempted to cleanup some of the help text as I found it to be a bit confusing and added phpdoc and a few inline comments.

The main change I made was removing the feature that used information from drupal.org to split the list of commit messages up by category. I don't really think this is necessary for this script as it's adding additional functionality that the script didn't have before.

As the person creating the release note I would rather use this as a script to help me get started and then if I wanted to I could go in and re-arrange things using my own conventions.

Also, it's not really a good idea to be pulling information from drupal.org for every single issue. Just imagine what would happen if someone did drush rn 3.0 7.0 in core, that's a lot of page requests. Yikes!

I've attached my version of the drush command. This should still get turned into a patch for the devel module as per comments above.

For reference the command now outputs something like this:

<p>Changes since 6.x-1.0:</p>
<ul>
<li>Preparing new release.</li>
<li><a href="/node/630290">#630290</a> by grendzy: Fixed views integration ignores global breadcrumb setting.</li>
<li><a href="/node/632070">#632070</a> by sun, nemchenk: Fixed first group removed from $node->og_groups.</li>
<li><a href="/node/547634">#547634</a> by eojthebrave, sun: Fixed wrong node parent assigned via taxonomy term.</li>
</ul>
Josh The Geek’s picture

Oy! When I added that, it was a todo in cvs-release-notes, and I wasn't really thinking. Maybe after some apis come out I'll reimplement it. Sorry! :(
Note: I have git 1.7.3.1 (git --version)
I'll fix this after breakfast.

Josh The Geek’s picture

Patch:

diff --git grn.drush.inc grn.drush.inc
index 7e829d0..d0432ae 100644
--- grn.drush.inc
+++ grn.drush.inc
@@ -68,6 +68,7 @@ function drush_grn_release_notes($tag1n, $tag2n) {
     $git = drush_get_option('git');
     $additional = ' with Git at !git.';
   }
+  $get = FALSE; // Set this to TRUE to get category. Otherwise, not used.
   //drush_log(dt('Generating release notes between !tag1 and !tag2' . $additional, array('!tag1' => $tag1n, '!tag2' => $tag2n, '!git' => $git)));
   chdir(getcwd());
   if (!is_dir(".git")) {
@@ -81,7 +82,7 @@ function drush_grn_release_notes($tag1n, $tag2n) {
     return drush_set_error('DRUSH_INVALID_TAG', dt('!tag is not a valid Git tag.', array('!tag' => $tag2n)), 'error');
   }
   $tag2 = drush_shell_exec_output();
-  $changes = _drush_grn_get_changes($tag1[0], $tag2[0], $git);
+  $changes = _drush_grn_get_changes($tag1[0], $tag2[0], $git, $get);
   echo _drush_grn_print_changes($changes, $tag1n);
 }
 
@@ -94,14 +95,14 @@ function _drush_grn_print_changes($changes, $prev_tag) {
   $return = "<p>Changes since $prev_tag:</p>\n";
   $return .= "<ul>\n";
   foreach ($changes as $type => $issues) {
-    $return .= "<li>$type<ul>\n";
+    if ($type != '') { $return .= "<li>$type<ul>\n"; }
     foreach ($issues as $number => $line) {
       $print = '<li>' . preg_replace('/^(Patch |- |Issue ){0,3}/', '', preg_replace('/#(\d+)/', '<a href="/node/$1">#$1</a>', $line)) . "</li>\n";
       if ($print != "<li></li>\n") {
         $return .= $print;
       }
     }
-    $return .= "</ul></li>\n";
+    if ($type != '') { $return .= "</ul></li>\n"; }
   }
   $return .= "</ul>\n";
   return $return;
@@ -110,19 +111,19 @@ function _drush_grn_print_changes($changes, $prev_tag) {
 /**
  * Get the changes, and return them in an array sorted by issue type, if available
  */
-function _drush_grn_get_changes($tag1, $tag2, $git) {
+function _drush_grn_get_changes($tag1, $tag2, $git, $get) {
   $changes = array();
   if (!drush_shell_exec("%s log -s --format=%%B %s..%s", $git, $tag1, $tag2)) {
     return drush_set_error('DRUSH_GIT_LOG_ERROR', 'git log returned an error.');
   }
   $output = drush_shell_exec_output();
-  $changes[_drush_grn_get_issue_type($output[0])][] = $output[0]; // Otherwise, next() would skip first
+  $changes[_drush_grn_get_issue_type($output[0], $get)][] = $output[0]; // Otherwise, next() would skip first
   while (($line = next($output)) !== false) {
       if ($line == '') {
         // Skip blank lines that are left behind in the messages.
         continue;
       }
-      $changes[_drush_grn_get_issue_type($line)][] = $line;
+      $changes[_drush_grn_get_issue_type($line, $get)][] = $line;
     }
   return $changes;
 }
@@ -130,7 +131,12 @@ function _drush_grn_get_changes($tag1, $tag2, $git) {
 /**
  * Return the pretty name of the category of the first issue mentioned in the message
  */
-function _drush_grn_get_issue_type($line) {
+function _drush_grn_get_issue_type($line, $get = FALSE) {
+  // Only get type if $get is TRUE
+  if (!$get) {
+    $return = '';
+    return $return;
+  }
   preg_match('/#(\d+)/', $line, $matches);
   if (!isset($matches[1]) || empty($matches[1])) {
     return $return = 'Other changes:';
Josh The Geek’s picture

Commited.

Josh The Geek’s picture

6.x-2.2 (https://github.com/JoshTheGeek/git-release-notes/tarball/6.x-2.2)
Branch drush-category and master exit with a note about the unholy things they do. (drush-category is an easy way for me to go back and add support for apis if/when they come out)
master, you just shouldn't use anyways

eojthebrave’s picture

Yeah bummer that we can't do all the fancy stuff but unfortunately the drupal.org infrastructure would probably just go up in flames.

I'm not sure how I feel about having a bunch of extra code in the script that doesn't ever actually get executed. While I like the idea of having a working example that shows what is possible when it comes to log parsing and collecting more contextual information from d.o. I think we're better off keeping that out of the code until d.o. has the infrastructure to support it. I'm a stickler for clean code. Especially if this is going to get included as part of a well known and oft used module. :)

I would also still like to see the cleanup changes that I made applied as well. It's mostly just coding standards stuff, adding some phpdoc to the functions and renaming the $tag1, and $tag2 variables to $start_tag and $end_tag for more clarity.

In order to get this done and usable ASAP I propose we use my modified version of Josh's code from #23 and implement the release-notes command as part of the devel module. (Patch against devel 7.x-1.x-dev attached). And then continue development of the fancier version of the script either in Josh's github repo or in a new drupal.org sandbox once the git migration is complete.

This way we've got something that people can make use of for now and can continue development of better version as the d.o. API's/Infrastructure matures.

Josh, I'm happy to provide a patch or a pull-request for your git repo if you'd like. Just let me know.

Josh The Geek’s picture

Hmm. I was going to create another project for it after tggm, and just push to d.o, with branches renamed.
I think we should wait with merging with devel.drush.inc, but I'd take a pull request/patch (whichever is easiest) that adds some doxy and removes unneeded code. (renaming the vars will work)
Also, in your patch in #28, in_format_output, its missing a regex that removes any combination of Patch, -, or Issue from the very front, to clean up the output. I have that line as

$print = '<li>' . preg_replace('/^(Patch |- |Issue ){0,3}/', '', preg_replace('/#(\d+)/', '<a href="/node/$1">#$1</a>', $line)) . "</li>\n";

(The issue prefix is not standard, but may be post tggm: #1059966: Change recommended format for commit messages (no more '#1234 by abc'))

webchick’s picture

Moving to the Devel module queue.

I'm in support of this approach, too. I'd love to get the simplest 1:1 conversion possible in Devel ASAP so it's there on migration day, and then add on fancy features afterwards if necessary. Preferably without creating a DDOS attack on Drupal.org. :D

In fact, a simple way to do that "per-category" feature in the future would be to simply parse the log messages according to the rules outlined at http://drupal.org/node/1061754 under "Give details", where you look for commit messages that start with Added (features), Fixed (bugs), Changed/Updated (task) and segment them appropriately that way. This way, those who follow the rules get the nice formatting, those who don't are encouraged to follow the rules. ;) But I'd still say that the default output of this script should still simply be chronological, and an extra parameter for "fancy" version, since it's not guaranteed to be remotely right, regardless of method.

But anyway, let's talk about that after this initial version gets committed. :)

Reviewing the patch, I found one "oopsie":

+      'end tag' => 'Tag or branch to end on. Must The current tag, the ending point for the log. This can be a branch, too, see example 2.',

This looked like a half-converted help text string. I changed this to just:

+      'end tag' => 'Tag or branch to end on.',

...since that matches the line above it.

However, I noticed kind of a funny behaviour. I have a git clone of drupal core and within it a git clone of Devel module so I can use this command. I cd into the sites/all/modules/devel and then do:

drush rn 6.x-1.17 6.x-1.18

It tells me:

6.x-1.17 is not a valid Git tag.                                     [error]

But that's funny, because it sure shows up when I type "git tag"...

The following works:

drush rn 6.17 6.20

...but that's because it's somehow inheriting core's .git directory instead of Devel module's. I assume.

This should be changed so that the command works relative to the directory it's called from.

webchick’s picture

Project: The Great Git Migration » Devel
Version: » 7.x-1.x-dev
Component: Migration scripts » devel

Ahem. Moving. :P

Josh The Geek’s picture

Its still missing a regex
I'm not sure what's happening there, I just use the output of git show and pass it to git log.
Can we please not merge this with devel? I would like to have a separate module for it, so that I can have a git checkout of grn in ~/.drush, and not have the whole devel module in there too. It will make things less confusing.

kika’s picture

subscribing

Josh The Geek’s picture

Josh The Geek’s picture

Project: Devel » Git Release Notes for Drush
Version: 7.x-1.x-dev » 6.x-2.x-dev
Component: devel » Code
Issue tags: -git sprint 9

Move to that issue queue. Also, not really sprint 9.

jcnventura’s picture

Status: Needs review » Fixed

Since there's already a release of the drush script, I would think it best to close this dev thread.

Bugs with that script should open their own grn issues.

Status: Fixed » Closed (fixed)
Issue tags: -git phase 3, -git low hanging fruit, -git phase 2 leftovers

Automatically closed -- issue fixed for 2 weeks with no activity.