package VCP::Utils; =head1 NAME VCP::Utils - utilities used within VCP's modules. =head1 SYNOPSIS use VCP::Utils qw( shell_quote ); =head1 DESCRIPTION A mix-in class providing methods shared by VCP::Source::cvs and VCP::Dest::cvs, mostly wrappers for calling the cvs command. =cut @EXPORT_OK = qw( empty escape_filename is_win32 program_name start_dir_rel2abs shell_quote start_dir xchdir ); @ISA = qw( Exporter ); use Exporter; use Cwd; use strict; use File::Spec; use File::Basename qw( basename ); use VCP::Logger qw( lg pr program_name BUG ); use constant is_win32 => $^O =~ /Win32/; my $start_dir; BEGIN { $start_dir = cwd } =head1 FUNCTIONS =over =item shell_quote my $line = shell_quote \@command; my $line = shell_quote @command; print STDERR, $line, "\n"; Selectively quotes the command line to allow it to be printed in a non-vague fashion and to be pastable in the local shell (sh/bash on Unix, COMMAND.COM, etc. on Win32 and OS2). NOTE: May not be perfect; errs on the side of safety and doesn't try to escape things right on Win32 yet. Patches welcome. =cut { my $q; BEGIN { $q = is_win32 ? '"' : "'" }; sub shell_quote { my @parms = ref $_[0] eq "ARRAY" ? @{$_[0]} : @_; return join " ", map { defined $_ ? m{[^\w:/\\.,=\@-]} ? do { ( my $s = $_ ) =~ s/([\\$q])/\\$1/; "$q$s$q"; } : $_ : "(((undef)))"; } @parms; } } =item empty Determines if a scalar value is empty, that is not defined or zero length. =cut sub empty($) { return ! ( defined $_[0] && length $_[0] ); } =item escape_filename Escape a string so that it may be used as a filename. Converts characters other than "-", "_", and alphanumerics to %NN% escape sequences where NN is the ordinal value (usually the ASCII value or UTF-8 codepoint) of the character. =cut sub escape_filename { my ($s) = @_; BUG "usage: escape_filename <filename-to-escape>" if empty $s; $s =~ s/([^0-9a-zA-Z\-_])/sprintf '%%%d%%', ord $1/eg ; return $s; } =item start_dir_rel2abs start_dir_rel2abs( $fn ); If $fn is a relative path (according to File::Spec), converts it to an absolute path using start_dir() as the base directory. =cut sub start_dir_rel2abs { BUG "start_dir_rel2abs() takes one and only one argument" unless @_ == 1; my $p = File::Spec->rel2abs( @_, $start_dir ); return $p unless is_win32; $p =~ s{\\+}{/}g; return $p; } =item start_dir Returns the directory that was current when VCP::Utils was parsed. =cut sub start_dir { $start_dir } =item xchdir Changes to a directory (unless we're already in that directory) and logs the change. Throws an exception on error. Sets $ENV{PWD}. You should use minimal canonical paths where possible so that $ENV{PWD} is a simple path. Some child processes might not like paths with thisdir ("/./") or updir segments ("/../"). Relative paths are an error. =cut { my %abs_cache; my $cwd = start_dir; sub xchdir($) { my $to_dir = shift; return if $cwd eq $to_dir; BUG "can't chdir() to relative path '$to_dir'" unless $abs_cache{$to_dir} ||= File::Spec->file_name_is_absolute( $to_dir ); lg "\$ ", shell_quote "chdir", $to_dir; chdir $to_dir or die "vcp: $!: $to_dir"; $cwd = $ENV{CWD} = $to_dir; } } =back =head1 COPYRIGHT Copyright 2000, Perforce Software, Inc. All Rights Reserved. This module and the VCP package are licensed according to the terms given in the file LICENSE accompanying this distribution, a copy of which is included in L<vcp>. =cut 1 ;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#35 | 4143 | barrie_slaymaker | - Further adaptation to vcp.exe packaging format | ||
#34 | 4141 | barrie_slaymaker | - Adapt online help and html generation to vcp.exe environment | ||
#33 | 3714 | barrie_slaymaker | - Minor import cleanup | ||
#32 | 3642 | barrie_slaymaker | - First cut at PAR based script to build vcp.exe | ||
#31 | 3569 | barrie_slaymaker |
- Work around bug caused by p4's using the long pathname when $ENV{PWD} is not set. |
||
#30 | 3532 | john_fetkovich |
changed File::Spec->rel2abs( blah, start_dir ) to start_dir_rel2abs blah everywhere. which does the same thing and is defined in VCP::Utils |
||
#29 | 3496 | barrie_slaymaker | - VSS branching | ||
#28 | 3464 | barrie_slaymaker |
- Create VCP::ConfigFileUtils and move bin/vcp::parse_config_file in to it. - Add VCP::ConfigFileUtils::write_config_file() - Add --output-vcp-file to bin/vcp. - Add VCP::Driver::repo_spec_as_string() - Add VCP::Driver::config_file_section_as_string() - VCP::Driver::parse_repo_spec() now clears any settings that are not set by a given spec string (so old values don't remain after a call to it). |
||
#27 | 3412 | barrie_slaymaker | - Add VCP::Utils::is_win32() | ||
#26 | 3167 | barrie_slaymaker |
Add profiling report that details various chunks of time taken. |
||
#25 | 3162 | barrie_slaymaker | Fix suprise interpolation in shell quoting RE | ||
#24 | 3155 | barrie_slaymaker |
Convert to logging using VCP::Logger to reduce stdout/err spew. Simplify & speed up debugging quite a bit. Provide more verbose information in logs. Print to STDERR progress reports to keep users from wondering what's going on. Breaks test; halfway through upgrading run3() to an inline function for speed and for VCP specific features. |
||
#23 | 3105 | barrie_slaymaker | Tweak to profiling code | ||
#22 | 3008 | john_fetkovich |
make state database files go under vcp_state in the program start directory (start_dir) instead of start_dir itself. Also escape periods (.) from the database directory as well as the characters already escaped. |
||
#21 | 2972 | barrie_slaymaker | Interim checkin | ||
#20 | 2941 | john_fetkovich | fix escape_filename | ||
#19 | 2936 | john_fetkovich | add empty() calls | ||
#18 | 2935 | john_fetkovich | added empty() calls | ||
#17 | 2928 | john_fetkovich |
Added empty sub to VCP::Utils.pm to check for empty or undefined strings. Added a couple of calls to it in Dest.pm. |
||
#16 | 2926 | john_fetkovich |
remove --state-location switch add --db-dir and --repo-id switches build state location from concatenation of those two. |
||
#15 | 2728 | john_fetkovich | oops, fix syntax error | ||
#14 | 2727 | john_fetkovich | more profiling capability added. | ||
#13 | 2701 | barrie_slaymaker | Add support for start_dir | ||
#12 | 2683 | john_fetkovich |
VCPPROFILETIME environment var now controls if unix 'time' dumps elapsed times into profile log. |
||
#11 | 2679 | john_fetkovich | profiling fixes | ||
#10 | 2670 | john_fetkovich | get and use full path of time command when profiling | ||
#9 | 2669 | john_fetkovich | spelling fix | ||
#8 | 2668 | john_fetkovich | die if prepend_time_command called when profiling is off. | ||
#7 | 2661 | john_fetkovich | fix profiling so it determines absolute path of profiling log file | ||
#6 | 2655 | john_fetkovich |
Added usage of 'nix time command to run_safely in Utils.pm when profiling is turned on. |
||
#5 | 2654 | john_fetkovich | profiling tweaks. | ||
#4 | 2639 | john_fetkovich |
Added profiling to be made active when VCPPROFILE environment variable turned on. writes profile info to filename defined in VCPPROFILE. Put some profiling statements (activated at compile time) in vcp and p4.pm. |
||
#3 | 2300 | barrie_slaymaker | improve shell quoting a bit | ||
#2 | 2293 | barrie_slaymaker | Update CHANGES, TODO, improve .vcp files, add --init-cvs | ||
#1 | 2267 | barrie_slaymaker | factor out cvs2revml, test both --use-cvs and direct modes, with times |