⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subversion.pm

📁 codestriker is a develop useful tool to review code on web user interface.
💻 PM
字号:
################################################################################ Codestriker: Copyright (c) 2001,2002,2003 David Sitsky.  All rights reserved.# sits@users.sourceforge.net## This program is free software; you can redistribute it and modify it under# the terms of the GPL.# Subversion repository access package.package Codestriker::Repository::Subversion;use IPC::Open3;use strict;use Fatal qw / open close /;use Codestriker::Repository;@Codestriker::Repository::Subversion::ISA = ("Codestriker::Repository");# Constructor, which takes as a parameter the repository url.sub new {    my ($type, $repository_url, $user, $password) = @_;    # Sanitise the repository URL.    $repository_url = sanitise_url_component($repository_url);    # Set the repository string.    my $repository_string = $repository_url;    $repository_string .= ";$user" if defined $user;    $repository_string .= ";$password" if defined $password;    if ($repository_string !~ /^svn:/) {        $repository_string = "svn:" . $repository_string;    }    my $self = Codestriker::Repository->new($repository_string);    $self->{repository_url} = $repository_url;    # Determine if there are additional parameters required for user    # authentication.    my @userCmdLine = ();    if (defined($user) && defined($password)) {        push @userCmdLine, '--username';        push @userCmdLine, $user;        push @userCmdLine, '--password';        push @userCmdLine, $password;    }    $self->{userCmdLine} = \@userCmdLine;    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) = @_;    # Sanitise the filename.    $filename = sanitise_url_component($filename);    my $read_data = '';    my $read_stdout_fh = new FileHandle;    open($read_stdout_fh, '>', \$read_data);    my @args = ();    push @args, 'cat';    push @args, '--non-interactive';    push @args, '--no-auth-cache';    push @args, @{ $self->{userCmdLine} };    push @args, $self->{repository_url} . '/' . $filename . '@' . $revision;    Codestriker::execute_command($read_stdout_fh, undef,                                 $Codestriker::svn, @args);    # Process the data for the topic.    open($read_stdout_fh, '<', \$read_data);    for (my $i = 1; <$read_stdout_fh>; $i++) {        $_ = Codestriker::decode_topic_text($_);        chop;        $$content_array_ref[$i] = $_;    }    return $Codestriker::OK;}# Retrieve the "root" of this repository.sub getRoot ($) {    my ($self) = @_;    return $self->{repository_url};}# Given a Subversion URL, determine if it refers to a directory or a file.sub is_file_url {    my ($self, $url, $revision) = @_;    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 . '@' . $revision;        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 =~ /^File$/io;                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, $self->{repository_url} . '/' . $url . '@' . $revision;        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 {    my ($self, $start_tag, $end_tag, $module_name, $stdout_fh, $stderr_fh) = @_;    my $revision;    my $removed_file = 0;    if ($start_tag eq "" && $end_tag ne "") {        $revision = $end_tag;    } elsif ($start_tag ne "") {	if ($end_tag eq "") {	    $revision = $start_tag;	} elsif ($end_tag eq $Codestriker::REMOVED_REVISION) {	    # Indicates a removed file.	    $revision = $start_tag;	    $removed_file = 1;	}    }    # 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, defined $revision ? $revision : $start_tag)) {        $module_name =~ /(.*)\/[^\/]+/;        $directory = $1;    } else {        $directory = $module_name;    }    # Execute the diff command.    my $read_stdout_data = '';    my $read_stdout_fh = new FileHandle;    open($read_stdout_fh, '>', \$read_stdout_data);    my @args = ();    my $last_line;    if (defined $revision) {        # Just pull out the actual contents of the file.        push @args, 'cat';        push @args, '--non-interactive';        push @args, '--no-auth-cache';        push @args, @{ $self->{userCmdLine} };        push @args, $self->{repository_url} . '/' . $module_name . '@' . $revision;        Codestriker::execute_command($read_stdout_fh, $stderr_fh,                                     $Codestriker::svn, @args);	# First determine the line count.        open($read_stdout_fh, '<', \$read_stdout_data);        my $number_lines = 0;        while (<$read_stdout_fh>) {            $number_lines++;        }        # Fake the diff header.        print $stdout_fh "Index: $module_name\n";        print $stdout_fh "===================================================================\n";	my $prefix;	if ($removed_file) {	    print $stdout_fh "--- $module_name\t(revision $revision)\n";	    print $stdout_fh "+++ /dev/null\n";	    print $stdout_fh "@@ -1,$number_lines +0,0 @@\n";	    $prefix = '-';	} else {	    print $stdout_fh "--- /dev/null\n";	    print $stdout_fh "+++ $module_name\t(revision $revision)\n";	    print $stdout_fh "@@ -0,0 +1,$number_lines @@\n";	    $prefix = '+';	}        # Now write out the content.        open($read_stdout_fh, '<', \$read_stdout_data);        while (<$read_stdout_fh>) {	    $last_line ="$prefix $_";            print $stdout_fh $last_line;        }    } else {        push @args, 'diff';        push @args, '--non-interactive';        push @args, '--no-auth-cache';        push @args, @{ $self->{userCmdLine} };        push @args, '-r';        push @args, $start_tag . ':' . $end_tag;        push @args, '--old';        push @args, $self->{repository_url};        push @args, $module_name;        Codestriker::execute_command($read_stdout_fh, $stderr_fh,                                     $Codestriker::svn, @args);        open($read_stdout_fh, '<', \$read_stdout_data);        while (<$read_stdout_fh>) {            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\//;                }            }            print $stdout_fh $line;	    $last_line = $line;        }    }    # Make sure the last line has a new-line, so when creating text for    # ScmBug they are all appended correctly.    if (defined $last_line && substr($last_line, length($last_line)-1, 1) ne "\n") {	print $stdout_fh "\n";    }    return $Codestriker::OK;}1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -