User: sits
Date: 07/07/12 02:49:03
Modified: lib Codestriker.pm
lib/Codestriker/Repository Cvs.pm Subversion.pm
Log:
* Codestriker now behaves correctly under mod_perl when retrieving
data externally from an SCM system, such as when the Parallel link
is clicked, or when a topic is created directly from the SCM.
* Creating Subversion topics directly from the SCM now works correctly
in non-English locales.
Index: Codestriker.pm
===================================================================
RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker.pm,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -r1.100 -r1.101
--- Codestriker.pm 3 Jul 2007 10:00:24 -0000 1.100
+++ Codestriker.pm 12 Jul 2007 09:49:02 -0000 1.101
@@ -560,8 +560,10 @@
my $stderr_filename = "$command_tmpdir/stderr.txt";
# Thankfully this works under Windows.
- my $system_line = "$command_line > \"$stdout_filename\" 2>
\"$stderr_filename\"";
- system($system_line) == 0 || croak "Failed to execute $system_line:
$!\n";
+ my $system_line =
+ "$command_line > \"$stdout_filename\" 2> \"$stderr_filename\"";
+ system($system_line) == 0 ||
+ croak "Failed to execute $system_line: $!\n";
open(TMP_STDOUT, $stdout_filename);
binmode TMP_STDOUT;
@@ -600,20 +602,19 @@
waitpid($pid, 0);
}
};
- if ($@) {
- my $error_string = "Command failed: [EMAIL PROTECTED]";
- $error_string .= "$command " . join(' ', @args) . "\n";
- $error_string .= "Check your webserver error log for more
information.\n";
- print $stderr_fh $error_string;
- print STDERR $error_string;
- flush STDERR;
- }
+ my $exception = $@;
# Make sure the temporary directory is removed if it was created.
if (defined $command_tmpdir) {
rmtree($command_tmpdir);
}
+ if ($exception) {
+ croak("Command failed: [EMAIL PROTECTED]",
+ "$command " . join(' ', @args) . "\n",
+ "Check your webserver error log for more information.\n");
+ }
+
# Flush the output file handles.
$stdout_fh->flush;
$stderr_fh->flush;
Index: Cvs.pm
===================================================================
RCS file: /cvsroot/codestriker/codestriker/lib/Codestriker/Repository/Cvs.pm,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Cvs.pm 3 Jul 2007 06:29:38 -0000 1.7
+++ Cvs.pm 12 Jul 2007 09:49:02 -0000 1.8
@@ -11,6 +11,7 @@
use strict;
use FileHandle;
+use Fatal qw / open close /;
# Factory method for creating a local CVS repository object.
sub build_local {
@@ -64,7 +65,7 @@
my $read_data;
my $read_stdout_fh = new FileHandle;
- open($read_stdout_fh, '>', \$read_data) || die "Can't create in-memory
fh: $!";
+ open($read_stdout_fh, '>', \$read_data);
my @args = ();
push @args, '-q';
push @args, '-d';
@@ -78,7 +79,7 @@
$Codestriker::cvs, @args);
# Process the data for the topic.
- open($read_stdout_fh, '<', \$read_data) || die "Can't create in-memory
fh: $!";
+ open($read_stdout_fh, '<', \$read_data);
for (my $i = 1; <$read_stdout_fh>; $i++) {
$_ = Codestriker::decode_topic_text($_);
chop;
Index: Subversion.pm
===================================================================
RCS file:
/cvsroot/codestriker/codestriker/lib/Codestriker/Repository/Subversion.pm,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- Subversion.pm 3 Jul 2007 11:07:50 -0000 1.17
+++ Subversion.pm 12 Jul 2007 09:49:02 -0000 1.18
@@ -11,9 +11,10 @@
use IPC::Open3;
use strict;
+use Fatal qw / open close /;
# Constructor, which takes as a parameter the repository url.
-sub new ($$) {
+sub new {
my ($type, $repository_url, $user, $password) = @_;
# Determine if there are additional parameters required for user
@@ -26,35 +27,45 @@
push @userCmdLine, $password;
}
- # Make sure the repo url does not end in a /, the
- # rest of the module assumes that it does not.
- $repository_url =~ s/[\\\/]^//;
-
- # Replace any spaces with %20 uri friendly escapes.
- # Ditto with @ symbols, so Subversion doesn't interpret it as a peg.
- $repository_url =~ s/ /%20/g;
- $repository_url =~ s/\@/%40/g;
+ # Sanitise the repository URL.
+ $repository_url = sanitise_url_component($repository_url);
my $self = {};
$self->{repository_url} = $repository_url;
$self->{userCmdLine} = [EMAIL PROTECTED];
+ $self->{repository_string} = $repository_url;
+ $self->{repository_string} .= ";$user" if defined $user;
+ $self->{repository_string} .= ";$password" if defined $password;
+ if ($self->{repository_string} !~ /^svn:/) {
+ $self->{repository_string} = "svn:" . $self->{repository_string};
+ }
bless $self, $type;
}
+# Sanitise a Subversion URL component, by replacing spaces with %20 and @
+# symbols with %40, so that there is no confused with pegged revisions. Also
+# remove any leading and trailing slashes.
+sub sanitise_url_component {
+ my $url = shift;
+ $url =~ s/\/$//;
+ $url =~ s/^\///;
+ $url =~ s/ /%20/g;
+ $url =~ s/\@/%40/g;
+ return $url;
+}
+
# Retrieve the data corresponding to $filename and $revision. Store each
line
# into $content_array_ref.
sub retrieve ($$$\$) {
my ($self, $filename, $revision, $content_array_ref) = @_;
- # Replace any spaces with %20 uri friendly escapes.
- # Ditto with @ symbols, so Subversion doesn't interpret it as a peg.
- $filename =~ s/ /%20/g;
- $filename =~ s/\@/%40/g;
+ # Sanitise the filename.
+ $filename = sanitise_url_component($filename);
my $read_data;
my $read_stdout_fh = new FileHandle;
- open($read_stdout_fh, '>', \$read_data) || die "Can't create in-memory
fh: $!";
+ open($read_stdout_fh, '>', \$read_data);
my @args = ();
push @args, 'cat';
push @args, '--non-interactive';
@@ -67,7 +78,7 @@
$Codestriker::svn, @args);
# Process the data for the topic.
- open($read_stdout_fh, '<', \$read_data) || die "Can't create in-memory
fh: $!";
+ open($read_stdout_fh, '<', \$read_data);
for (my $i = 1; <$read_stdout_fh>; $i++) {
$_ = Codestriker::decode_topic_text($_);
chop;
@@ -87,6 +98,10 @@
# Lookup the file viewer from the configuration.
my $viewer = $Codestriker::file_viewer->{$self->toString()};
+ if (! (defined $viewer)) {
+ $viewer = $Codestriker::file_viewer->{$self->{repository_string}};
+ }
+
return (defined $viewer) ? $viewer . "/" . $filename : "";
}
@@ -96,79 +111,90 @@
return "svn:" . $self->getRoot();
}
+# Given a Subversion URL, determine if it refers to a directory or a file.
+sub is_file_url {
+ my ($self, $url) = @_;
+ my $file_url;
+
+ eval {
+ my @args = ();
+ push @args, 'info';
+ push @args, '--non-interactive';
+ push @args, '--no-auth-cache';
+ push @args, @{ $self->{userCmdLine} };
+ push @args, '--xml';
+ push @args, $self->{repository_url} . '/' . $url;
+ my $read_data;
+ my $read_stdout_fh = new FileHandle;
+ open($read_stdout_fh, '>', \$read_data);
+
+ Codestriker::execute_command($read_stdout_fh, undef,
+ $Codestriker::svn, @args);
+ open($read_stdout_fh, '<', \$read_data);
+ while (<$read_stdout_fh>) {
+ if (/kind\s*\=\s*\"(\w+)\"/) {
+ $file_url = $1 eq "File";
+ last;
+ }
+ }
+ };
+ if ($@ || !(defined $file_url)) {
+ # The above command failed, try using the older method which only works
+ # in an English locale. This supports Subversion 1.2 or earlier
+ # releases, which don't support the --xml flag for the info command.
+ my @args = ();
+ push @args, 'cat';
+ push @args, '--non-interactive';
+ push @args, '--no-auth-cache';
+ push @args, @{ $self->{userCmdLine} };
+ push @args, '--revision';
+ push @args, 'HEAD';
+ push @args, $self->{repository_url} . '/' . $url;
+
+ my $read_stdout_data;
+ my $read_stdout_fh = new FileHandle;
+ open($read_stdout_fh, '>', \$read_stdout_data);
+
+ my $read_stderr_data;
+ my $read_stderr_fh = new FileHandle;
+ open($read_stderr_fh, '>', \$read_stderr_data);
+
+ Codestriker::execute_command($read_stdout_fh, $read_stderr_fh,
+ $Codestriker::svn, @args);
+ $file_url = 1;
+ open($read_stderr_fh, '<', \$read_stderr_data);
+ while(<$read_stderr_fh>) {
+ if (/^svn:.* refers to a directory/) {
+ $file_url = 0;
+ last;
+ }
+ }
+ }
+
+ return $file_url;
+}
+
# The getDiff operation, pull out a change set based on the start and end
# revision number, confined to the specified moduled_name.
-sub getDiff ($$$$$) {
+sub getDiff {
my ($self, $start_tag, $end_tag, $module_name, $stdout_fh, $stderr_fh) =
@_;
- # Make sure the module does not end or start with a /
- $module_name =~ s/\/$//;
- $module_name =~ s/^\///;
-
- # Replace any spaces with %20 uri friendly escapes.
- # Ditto with @ symbols, so Subversion doesn't interpret it as a peg.
- my $filename = $module_name;
- $filename =~ s/ /%20/g;
- $filename =~ s/\@/%40/g;
+ # Sanitise the URL, and determine if it refers to a directory or
filename.
+ $module_name = sanitise_url_component($module_name);
+ my $directory;
+ if ($self->is_file_url($module_name)) {
+ $module_name =~ /(.*)\/[^\/]+/;
+ $directory = $1;
+ } else {
+ $directory = $module_name;
+ }
- my $write_stdin_fh = new FileHandle;
+ # Execute the diff command.
+ my $read_stdout_data;
my $read_stdout_fh = new FileHandle;
- my $read_stderr_fh = new FileHandle;
+ open($read_stdout_fh, '>', \$read_stdout_data);
my @args = ();
- push @args, 'cat';
- push @args, '--non-interactive';
- push @args, '--no-auth-cache';
- push @args, @{ $self->{userCmdLine} };
- push @args, '--revision';
- push @args, 'HEAD';
- push @args, $self->{repository_url} . '/' . $filename;
-
- my $pid = open3($write_stdin_fh, $read_stdout_fh, $read_stderr_fh,
- $Codestriker::svn, @args);
-
- while(<$read_stdout_fh>) {}
-
- my $directory;
-
- # TODO: need a better way of detecting this, since Chinese users
- # receive a different output string. Kind is either a file or
- # directory from what I have seen.
- # C:\Program Files\svn-win32-1.4.4\bin>svn info --xml
http://svn.collab.net/repos/svn/trunk/tools/README
-# <?xml version="1.0"?>
-# <info>
-# <entry
-# kind="file"
-# path="README"
-# revision="25631">
-# <url>http://svn.collab.net/repos/svn/trunk/tools/README</url>
-
- # If there is an error about it being a directory, then use the
- # module name as a directory.
- while(<$read_stderr_fh>) {
- my $line = $_;
-
- if ($line =~ /^svn:.*URL '.*' refers to a directory/) {
- $directory = $module_name;
- }
- }
-
- # if there was no error, then the module name is a file, so get the
- # directory before the file name.
- if (! defined $directory) {
- $module_name =~ /(.*)\/[^\/]+/;
- $directory = $1;
- }
-
- $write_stdin_fh->close();
- $read_stdout_fh->close();
- $read_stderr_fh->close();
-
- $write_stdin_fh = new FileHandle;
- $read_stdout_fh = new FileHandle;
- $read_stderr_fh = new FileHandle;
-
- @args = ();
push @args, 'diff';
push @args, '--non-interactive';
push @args, '--no-auth-cache';
@@ -178,47 +204,35 @@
push @args, '--old';
push @args, $self->{repository_url};
push @args, $module_name;
+ Codestriker::execute_command($read_stdout_fh, $stderr_fh,
+ $Codestriker::svn, @args);
- $pid = open3($write_stdin_fh, $read_stdout_fh, $read_stderr_fh,
- $Codestriker::svn, @args);
-
+ open($read_stdout_fh, '<', \$read_stdout_data);
while(<$read_stdout_fh>) {
- my $line = $_;
+ my $line = $_;
+
+ # If the user specifies a path (a branch in Subversion), the
+ # diff file does not come back with a path rooted from the
+ # repository base making it impossible to pull the entire file
+ # back out. This code attempts to change the diff file on the
+ # fly to ensure that the full path is present. This is a bug
+ # against Subversion, so eventually it will be fixed, so this
+ # code can't break when the diff command starts returning the
+ # full path.
+ if ($line =~ /^--- / || $line =~ /^\+\+\+ / ||
+ $line =~ /^Index: /) {
+ # Check if the bug has been fixed.
+ if ($line =~ /^\+\+\+ $module_name/ == 0 &&
+ $line =~ /^--- $module_name/ == 0 &&
+ $line =~ /^Index: $module_name/ == 0) {
+ $line =~ s/^--- /--- $directory\// or
+ $line =~ s/^Index: /Index: $directory\// or
+ $line =~ s/^\+\+\+ /\+\+\+ $directory\//;
+ }
+ }
- # If the user specifies a path (a branch in Subversion), the
- # diff file does not come back with a path rooted from the
- # repository base making it impossible to pull the entire file
- # back out. This code attempts to change the diff file on the
- # fly to ensure that the full path is present. This is a bug
- # against Subversion, so eventually it will be fixed, so this
- # code can't break when the diff command starts returning the
- # full path.
- if ($line =~ /^--- / || $line =~ /^\+\+\+ / || $line =~ /^Index: /) {
- # Check if the bug has been fixed.
- if ($line =~ /^\+\+\+ $module_name/ == 0 &&
- $line =~ /^--- $module_name/ == 0 &&
- $line =~ /^Index: $module_name/ == 0) {
-
- $line =~ s/^--- /--- $directory\// or
- $line =~ s/^Index: /Index: $directory\// or
- $line =~ s/^\+\+\+ /\+\+\+ $directory\//;
- }
- }
-
- print $stdout_fh $line;
- }
-
- my $buf;
- while (read($read_stderr_fh, $buf, 16384)) {
- print $stderr_fh $buf;
- }
-
- # Wait for the process to terminate.
- waitpid($pid, 0);
-
- # Flush the output file handles.
- $stdout_fh->flush;
- $stderr_fh->flush;
+ print $stdout_fh $line;
+ }
return $Codestriker::OK;
}
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Codestriker-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/codestriker-commits