📄 svn_load_dirs.pl.in
字号:
my @lines = read_from_process(@command); next unless @lines; if (@lines > 1) { warn "$0: '@command' returned more than one line of output: ", "'@lines'.\n"; next; } my $eol_style = $lines[0]; if ($eol_style eq 'native') { @diff_ignore_space_changes = ('-b'); if (&convert_file_to_native_eol($upd_file)) { print "Native eol-style conversion modified $upd_file.\n"; } } } } my $message = wrap('', '', "Load $load_dir into $repos_load_abs_path.\n"); read_from_process($svn, 'commit', @svn_use_repos_cmd_opts, '-m', $message); # If an update is not run now after a commit, then some file and # directory paths will have an older revisions associated with # them and any future commits will fail because they are out of # date. read_from_process($svn, 'update'); # Now remove any files and directories to be deleted in the # repository. if (@del_files) { rmtree(\@del_files, 1, 0); } # Now make the tag by doing a copy in the svn repository itself. if (defined $load_tag) { my $repos_tag_abs_path = length($repos_base_path_segment) ? "$repos_base_path_segment/$load_tag" : $load_tag; my $from_url = $repos_load_rel_path eq '.' ? $repos_load_rel_path : "$repos_base_url/$repos_load_rel_path"; my $to_url = "$repos_base_url/$load_tag"; $message = wrap("", "", "Tag $repos_load_abs_path as " . "$repos_tag_abs_path.\n"); read_from_process($svn, 'cp', @svn_use_repos_cmd_opts, '-m', $message, $from_url, $to_url); # Now check out the tag and run a recursive diff between the # original source directory and the tag for a consistency # check. my $checkout_dir_name = "my_tag_wc_named_$load_tag"; print "Checking out $to_url into $temp_dir/$checkout_dir_name\n"; chdir($temp_dir) or die "$0: cannot chdir '$temp_dir': $!\n"; read_from_process($svn, 'checkout', @svn_use_repos_cmd_opts, $to_url, $checkout_dir_name); chdir($checkout_dir_name) or die "$0: cannot chdir '$checkout_dir_name': $!\n"; chdir($orig_cwd) or die "$0: cannot chdir '$orig_cwd': $!\n"; read_from_process('diff', '-u', @diff_ignore_space_changes, '-x', '.svn', '-r', $load_dir, "$temp_dir/$checkout_dir_name"); } }exit 0;sub usage{ warn "@_\n" if @_; die "usage: $0 [options] svn_url svn_import_dir [dir_v1 [dir_v2 [..]]]\n", " svn_url is the file:// or http:// URL of the svn repository\n", " svn_import_dir is the path relative to svn_url where to load dirs\n", " dir_v1 .. list dirs to import otherwise read from stdin\n", "options are\n", " -no_user_input don't ask yes/no questions and assume yes answer\n", " -p filename table listing properties to apply to matching files\n", " -svn_username username to perform commits as\n", " -svn_password password to supply to svn commit\n", " -t tag_dir create a tag copy in tag_dir, relative to svn_url\n", " -v increase program verbosity, multiple -v's allowed\n", " -wc path use the already checked-out working copy at path\n", " instead of checkout out a fresh working copy\n";}# Get the next directory to load, either from the command line or from# standard input.my $get_next_load_dir_init = 0;my @get_next_load_dirs;sub get_next_load_dir{ if (@ARGV) { unless ($get_next_load_dir_init) { $get_next_load_dir_init = 1; @get_next_load_dirs = @ARGV; } return shift @get_next_load_dirs; } if ($opt_verbose) { print "Waiting for next directory to import on standard input:\n"; } my $line = <STDIN>; print "\n" if $opt_verbose; chomp $line; if ($line =~ m|(\S+)\s+(\S+)|) { $line = $1; set_svn_use_repos_cmd_opts($2, $opt_svn_password); } $line;}# This constant stores the commonly used string to indicate that a# subroutine has been passed an incorrect number of arguments.use vars qw($INCORRECT_NUMBER_OF_ARGS);$INCORRECT_NUMBER_OF_ARGS = "passed incorrect number of arguments.\n";# Creates a temporary file in the temporary directory and stores the# arguments in it for use by the svn --targets command line option.# If any part of the file creation failed, exit the program, as# there's no workaround. Use a unique number as a counter to the# files.my $make_targets_file_counter;sub make_targets_file{ unless (@_) { confess "$0: make_targets_file $INCORRECT_NUMBER_OF_ARGS"; } $make_targets_file_counter = 1 unless defined $make_targets_file_counter; my $filename = sprintf "%s/targets.%05d", $temp_dir, $make_targets_file_counter; ++$make_targets_file_counter; open(TARGETS, ">$filename") or die "$0: cannot open '$filename' for writing: $!\n"; foreach my $file (@_) { print TARGETS "$file\n"; } close(TARGETS) or die "$0: error in closing '$filename' for writing: $!\n"; $filename;}# Set the svn command line options that are used anytime svn connects# to the repository.sub set_svn_use_repos_cmd_opts{ unless (@_ == 2) { confess "$0: set_svn_use_repos_cmd_opts $INCORRECT_NUMBER_OF_ARGS"; } my $username = shift; my $password = shift; @svn_use_repos_cmd_opts = (); if (defined $username and length $username) { push(@svn_use_repos_cmd_opts, '--username', $username); } if (defined $password) { push(@svn_use_repos_cmd_opts, '--password', $password); }}sub get_tag_dir{ unless (@_ == 1) { confess "$0: get_tag_dir $INCORRECT_NUMBER_OF_ARGS"; } my $load_dir = shift; # Take the tag relative directory, search for pairs of # REGEX_SEP_CHAR's and use the regular expression inside the pair to # put in the tag directory name. my $tag_location = $opt_import_tag_location; my $load_tag = ''; while ((my $i = index($tag_location, $REGEX_SEP_CHAR)) >= 0) { $load_tag .= substr($tag_location, 0, $i, ''); substr($tag_location, 0, 1, ''); my $j = index($tag_location, $REGEX_SEP_CHAR); if ($j < 0) { die "$0: -t value '$opt_import_tag_location' does not have ", "matching $REGEX_SEP_CHAR.\n"; } my $regex = substr($tag_location, 0, $j, ''); $regex = "($regex)" unless ($regex =~ /\(.+\)/); substr($tag_location, 0, 1, ''); my @results = $load_dir =~ m/$regex/; $load_tag .= join('', @results); } $load_tag .= $tag_location; $load_tag;}# Return a two element array. The first element is a single character# that represents the type of object the path points to. The second# is a boolean (1 for true, '' for false) if the path points to a file# and if the file is executable.sub file_info{ lstat(shift) or return ('0', ''); -b _ and return ('b', ''); -c _ and return ('c', ''); -d _ and return ('d', ''); -f _ and return ('f', -x _); -l _ and return ('l', ''); -p _ and return ('p', ''); -S _ and return ('S', ''); return '?';}# Start a child process safely without using /bin/sh.sub safe_read_from_pipe{ unless (@_) { croak "$0: safe_read_from_pipe $INCORRECT_NUMBER_OF_ARGS"; } my $openfork_available = "MSWin32" ne $OSNAME; if ($openfork_available) { print "Running @_\n"; my $pid = open(SAFE_READ, "-|"); unless (defined $pid) { die "$0: cannot fork: $!\n"; } unless ($pid) { # child open(STDERR, ">&STDOUT") or die "$0: cannot dup STDOUT: $!\n"; exec(@_) or die "$0: cannot exec '@_': $!\n"; } } else { # Redirect the comment into a temp file and use that to work around # Windoze's (non-)handling of multi-line commands. my @commandline = (); my $command; my $comment; while ($command = shift) { if ("-m" eq $command) { my $comment = shift; my ($handle, $tmpfile) = tempfile(DIR => $temp_dir); print $handle $comment; close($handle); push(@commandline, "--file"); push(@commandline, $tmpfile); } else { # Munge the command to protect it from the command line $command =~ s/\"/\\\"/g; if ($command =~ m"\s") { $command = "\"$command\""; } if ($command eq "") { $command = "\"\""; } if ($command =~ m"\n") { warn "$0: carriage return detected in command - may not work\n"; } push(@commandline, $command); } } print "Running @commandline\n"; if ( $comment ) { print $comment; } # Now do the pipe. open(SAFE_READ, "@commandline |") or die "$0: cannot pipe to command: $!\n"; } # parent my @output; while (<SAFE_READ>) { chomp; push(@output, $_); } close(SAFE_READ); my $result = $?; my $exit = $result >> 8; my $signal = $result & 127; my $cd = $result & 128 ? "with core dump" : ""; if ($signal or $cd) { warn "$0: pipe from '@_' failed $cd: exit=$exit signal=$signal\n"; } if (wantarray) { return ($result, @output); } else { return $result; }}# Use safe_read_from_pipe to start a child process safely and exit the# script if the child failed for whatever reason.sub read_from_process{ unless (@_) { croak "$0: read_from_process $INCORRECT_NUMBER_OF_ARGS"; } my ($status, @output) = &safe_read_from_pipe(@_); if ($status) { print STDERR "$0: @_ failed with this output:\n", join("\n", @output), "\n"; unless ($opt_no_user_input) { print STDERR "Press return to quit and clean up svn working directory: "; <STDIN>; } exit 1; } else { return @output; }}# Get a list of all the files and directories in the specified# directory, the type of file and a digest hash of file types.sub recursive_ls_and_hash{ unless (@_ == 1) { croak "$0: recursive_ls_and_hash $INCORRECT_NUMBER_OF_ARGS"; } # This is the directory to change into. my $dir = shift; # Get the current directory so that the script can change into the # current working directory after changing into the specified # directory. my $return_cwd = cwd; chdir($dir) or die "$0: cannot chdir '$dir': $!\n"; my %files; my $wanted = sub { s#^\./##; return if $_ eq '.'; my ($file_type) = &file_info($_); my $file_digest; if ($file_type eq 'f' or ($file_type eq 'l' and stat($_) and -f _))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -