diff options
Diffstat (limited to 'attachment.cgi')
-rwxr-xr-x | attachment.cgi | 288 |
1 files changed, 27 insertions, 261 deletions
diff --git a/attachment.cgi b/attachment.cgi index 3939564a8..8541e8d5e 100755 --- a/attachment.cgi +++ b/attachment.cgi @@ -38,7 +38,6 @@ use strict; use lib qw(.); use Bugzilla; -use Bugzilla::Config qw(:localconfig); use Bugzilla::Constants; use Bugzilla::Error; use Bugzilla::Flag; @@ -48,6 +47,7 @@ use Bugzilla::Util; use Bugzilla::Bug; use Bugzilla::Field; use Bugzilla::Attachment; +use Bugzilla::Attachment::PatchReader; use Bugzilla::Token; Bugzilla->login(); @@ -350,272 +350,38 @@ sub view } -sub interdiff -{ - # Retrieve and validate parameters - my ($old_id) = validateID('oldid'); - my ($new_id) = validateID('newid'); - my $format = validateFormat('html', 'raw'); - my $context = validateContext(); - - # Get old patch data - my ($old_bugid, $old_description, $old_filename, $old_file_list) = - get_unified_diff($old_id); - - # Get new patch data - my ($new_bugid, $new_description, $new_filename, $new_file_list) = - get_unified_diff($new_id); - - my $warning = warn_if_interdiff_might_fail($old_file_list, $new_file_list); - - # - # send through interdiff, send output directly to template - # - # Must hack path so that interdiff will work. - # - $ENV{'PATH'} = $diffpath; - open my $interdiff_fh, "$interdiffbin $old_filename $new_filename|"; - binmode $interdiff_fh; - my ($reader, $last_reader) = setup_patch_readers("", $context); - if ($format eq 'raw') - { - require PatchReader::DiffPrinter::raw; - $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw()); - # Actually print out the patch - print $cgi->header(-type => 'text/plain', - -expires => '+3M'); - } - else - { - $vars->{warning} = $warning if $warning; - $vars->{bugid} = $new_bugid; - $vars->{oldid} = $old_id; - $vars->{old_desc} = $old_description; - $vars->{newid} = $new_id; - $vars->{new_desc} = $new_description; - delete $vars->{attachid}; - delete $vars->{do_context}; - delete $vars->{context}; - setup_template_patch_reader($last_reader, $format, $context); - } - $reader->iterate_fh($interdiff_fh, "interdiff #$old_id #$new_id"); - close $interdiff_fh; - $ENV{'PATH'} = ''; - - # - # Delete temporary files - # - unlink($old_filename) or warn "Could not unlink $old_filename: $!"; - unlink($new_filename) or warn "Could not unlink $new_filename: $!"; -} - -sub get_unified_diff -{ - my ($id) = @_; - my $dbh = Bugzilla->dbh; - - # Bring in the modules we need - require PatchReader::Raw; - require PatchReader::FixPatchRoot; - require PatchReader::DiffPrinter::raw; - require PatchReader::PatchInfoGrabber; - require File::Temp; - - # Get the patch - my ($bugid, $description, $ispatch, $thedata) = $dbh->selectrow_array( - "SELECT bug_id, description, ispatch, thedata " . - "FROM attachments " . - "INNER JOIN attach_data " . - "ON id = attach_id " . - "WHERE attach_id = ?", undef, $id); - if (!$ispatch) { - $vars->{'attach_id'} = $id; - ThrowCodeError("must_be_patch"); - } - - # Reads in the patch, converting to unified diff in a temp file - my $reader = new PatchReader::Raw; - my $last_reader = $reader; - - # fixes patch root (makes canonical if possible) - if (Bugzilla->params->{'cvsroot'}) { - my $fix_patch_root = - new PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'}); - $last_reader->sends_data_to($fix_patch_root); - $last_reader = $fix_patch_root; - } - - # Grabs the patch file info - my $patch_info_grabber = new PatchReader::PatchInfoGrabber(); - $last_reader->sends_data_to($patch_info_grabber); - $last_reader = $patch_info_grabber; - - # Prints out to temporary file - my ($fh, $filename) = File::Temp::tempfile(); - my $raw_printer = new PatchReader::DiffPrinter::raw($fh); - $last_reader->sends_data_to($raw_printer); - $last_reader = $raw_printer; - - # Iterate! - $reader->iterate_string($id, $thedata); - - return ($bugid, $description, $filename, $patch_info_grabber->patch_info()->{files}); -} - -sub warn_if_interdiff_might_fail { - my ($old_file_list, $new_file_list) = @_; - # Verify that the list of files diffed is the same - my @old_files = sort keys %{$old_file_list}; - my @new_files = sort keys %{$new_file_list}; - if (@old_files != @new_files || - join(' ', @old_files) ne join(' ', @new_files)) { - return "interdiff1"; - } - - # Verify that the revisions in the files are the same - foreach my $file (keys %{$old_file_list}) { - if ($old_file_list->{$file}{old_revision} ne - $new_file_list->{$file}{old_revision}) { - return "interdiff2"; - } - } - - return undef; -} - -sub setup_patch_readers { - my ($diff_root, $context) = @_; - - # - # Parameters: - # format=raw|html - # context=patch|file|0-n - # collapsed=0|1 - # headers=0|1 - # - - # Define the patch readers - # The reader that reads the patch in (whatever its format) - require PatchReader::Raw; - my $reader = new PatchReader::Raw; - my $last_reader = $reader; - # Fix the patch root if we have a cvs root - if (Bugzilla->params->{'cvsroot'}) - { - require PatchReader::FixPatchRoot; - $last_reader->sends_data_to( - new PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'})); - $last_reader->sends_data_to->diff_root($diff_root) if defined($diff_root); - $last_reader = $last_reader->sends_data_to; - } - # Add in cvs context if we have the necessary info to do it - if ($context ne "patch" && $cvsbin && Bugzilla->params->{'cvsroot_get'}) - { - require PatchReader::AddCVSContext; - $last_reader->sends_data_to( - new PatchReader::AddCVSContext($context, - Bugzilla->params->{'cvsroot_get'})); - $last_reader = $last_reader->sends_data_to; - } - return ($reader, $last_reader); -} - -sub setup_template_patch_reader -{ - my ($last_reader, $format, $context) = @_; - - require PatchReader::DiffPrinter::template; - - # Define the vars for templates - if (defined $cgi->param('headers')) { - $vars->{headers} = $cgi->param('headers'); - } else { - $vars->{headers} = 1 if !defined $cgi->param('headers'); - } - $vars->{collapsed} = $cgi->param('collapsed'); - $vars->{context} = $context; - $vars->{do_context} = $cvsbin && Bugzilla->params->{'cvsroot_get'} - && !$vars->{'newid'}; - - # Print everything out - print $cgi->header(-type => 'text/html', - -expires => '+3M'); - $last_reader->sends_data_to(new PatchReader::DiffPrinter::template($template, - "attachment/diff-header.$format.tmpl", - "attachment/diff-file.$format.tmpl", - "attachment/diff-footer.$format.tmpl", - { %{$vars}, - bonsai_url => Bugzilla->params->{'bonsai_url'}, - lxr_url => Bugzilla->params->{'lxr_url'}, - lxr_root => Bugzilla->params->{'lxr_root'}, - })); +sub interdiff { + # Retrieve and validate parameters + my ($old_id) = validateID('oldid'); + my ($new_id) = validateID('newid'); + my $format = validateFormat('html', 'raw'); + my $context = validateContext(); + + # XXX - validateID should be replaced by Attachment::check_attachment() + # and should return an attachment object. This would save us a lot of + # trouble. + my $old_attachment = Bugzilla::Attachment->get($old_id); + my $new_attachment = Bugzilla::Attachment->get($new_id); + + Bugzilla::Attachment::PatchReader::process_interdiff( + $old_attachment, $new_attachment, $format, $context); } -sub diff -{ - # Retrieve and validate parameters - my ($attach_id) = validateID(); - my $format = validateFormat('html', 'raw'); - my $context = validateContext(); - my $dbh = Bugzilla->dbh; - - # Get patch data - my ($bugid, $description, $ispatch, $thedata) = $dbh->selectrow_array( - "SELECT bug_id, description, ispatch, thedata FROM attachments " . - "INNER JOIN attach_data ON id = attach_id " . - "WHERE attach_id = ?", undef, $attach_id); - - # If it is not a patch, view normally - if (!$ispatch) - { - view(); - return; - } +sub diff { + # Retrieve and validate parameters + my ($attach_id) = validateID(); + my $format = validateFormat('html', 'raw'); + my $context = validateContext(); - my ($reader, $last_reader) = setup_patch_readers(undef,$context); + my $attachment = Bugzilla::Attachment->get($attach_id); - if ($format eq 'raw') - { - require PatchReader::DiffPrinter::raw; - $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw()); - # Actually print out the patch - print $cgi->header(-type => 'text/plain', - -expires => '+3M'); - $reader->iterate_string("Attachment $attach_id", $thedata); - } - else - { - $vars->{other_patches} = []; - if ($interdiffbin && $diffpath) { - # Get list of attachments on this bug. - # Ignore the current patch, but select the one right before it - # chronologically. - my $sth = $dbh->prepare("SELECT attach_id, description - FROM attachments - WHERE bug_id = ? - AND ispatch = 1 - ORDER BY creation_ts DESC"); - $sth->execute($bugid); - my $select_next_patch = 0; - while (my ($other_id, $other_desc) = $sth->fetchrow_array) { - if ($other_id eq $attach_id) { - $select_next_patch = 1; - } else { - push @{$vars->{other_patches}}, { id => $other_id, desc => $other_desc, selected => $select_next_patch }; - if ($select_next_patch) { - $select_next_patch = 0; - } - } - } + # If it is not a patch, view normally. + if (!$attachment->ispatch) { + view(); + return; } - $vars->{bugid} = $bugid; - $vars->{attachid} = $attach_id; - $vars->{description} = $description; - setup_template_patch_reader($last_reader, $format, $context); - # Actually print out the patch - $reader->iterate_string("Attachment $attach_id", $thedata); - } + Bugzilla::Attachment::PatchReader::process_diff($attachment, $format, $context); } # Display all attachments for a given bug in a series of IFRAMEs within one |