#!/usr/bin/perl -w #$Id: c4 709 2005-05-03 21:32:07Z wsnyder $ ###################################################################### # # Copyright 2002-2005 by Wilson Snyder. This program is free software; # you can redistribute it and/or modify it under the terms of either the GNU # General Public License or the Perl Artistic License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the Perl Artistic License # along with this module; see the file COPYING. If not, see # www.cpan.org # ###################################################################### require 5.006_001; use lib "blib/lib"; use lib "blib/arch"; use Getopt::Long; use IO::File; use Pod::Usage; use Cwd qw(getcwd chdir); use File::Find; use File::Spec; use File::Spec::Functions; use Carp; use strict; use P4::C4; use P4::C4::Path qw(fileNoLinks); use vars qw ($Debug); #====================================================================== $ENV{P4CONFIG} ||= '.p4config'; #====================================================================== # main autoflush STDOUT 1; autoflush STDERR 1; $Debug = 0; our $Opt_Cmd; our @Opt_CmdParams = (); our $P4Opt = new P4::Getopt; @ARGV = $P4Opt->parameter(@ARGV); Getopt::Long::config ("pass_through", "no_auto_abbrev"); if (! GetOptions ( "help" => \&usage, "debug" => \&debug, "<>" => \¶meter, )) { usage(); } if (!defined $Opt_Cmd) { usage(); } # Run relative to absolute cwd, so the client spec doesn't have links. # This is because perforce checks we match the client spec, but doesn't consider # symlinks to the same place to be good enough. chdir(fileNoLinks(getcwd())); # Set user, allowing a default if ($ENV{C4USER_DEFAULT} && !$ENV{P4USER}) { my $p4 = new P4::Client; $P4Opt->setClientOpt($p4); $p4->SetUser($ENV{C4USER_DEFAULT}); $p4->Init() or die "$0: %Error: Failed to connect to Perforce Server\n"; if (!$p4->isUser($ENV{P4USER}||$ENV{USER})) { $ENV{P4USER} = $ENV{C4USER_DEFAULT}; } } # Convert common CVS command names to what perforce wants $Opt_Cmd = "submit" if $Opt_Cmd eq "ci"; $Opt_Cmd = "submit" if $Opt_Cmd eq "commit"; $Opt_Cmd = "delete" if $Opt_Cmd eq "rm"; # Parse the command, and see if there are any file specs # Replace the file specs with absolute filenames, if possible. # Furthermore, chdir to the first one in an attempt to find the # right client file path. print "Cmd: ",join(' ',$Opt_Cmd),"\n" if $Debug; print " Pos: ",join(' ',@Opt_CmdParams),"\n" if $Debug; my @cmdParsed = $P4Opt->parseCmd($Opt_Cmd, @Opt_CmdParams); my @cmdOut; my $didCwd; my $pwd = getcwd(); for (my $i=0; $i<=$#cmdParsed; $i++) { my $arg = $Opt_CmdParams[$i]; my $parse = $cmdParsed[$i]; print " Arg $arg -> $parse\n" if $Debug; if ($parse =~ /^file/ && !P4::C4::Path::isDepotFilename($arg)) { $arg = catfile($arg,"...") if -d $arg; my $abs = fileNoLinks($arg); push @cmdOut, $abs; print " abs-> $abs\n" if $Debug; # Can we cwd there? if (!$didCwd && $abs) { my @dirlist = File::Spec->splitdir($abs); while ($#dirlist > 0) { my $fn = catdir(@dirlist); if (-d $fn) { $didCwd = $fn; print " SetCWD $fn\n" if $Debug; last; } pop @dirlist; } } } else { push @cmdOut, $arg; } } chdir($didCwd) if $didCwd; # Do last, else second file in list will be messed up @Opt_CmdParams = @cmdOut; # Execute comand if ($Opt_Cmd eq "change-max") { cmd_change_max(); } elsif ($Opt_Cmd eq "client-create") { cmd_client_create(); } elsif ($Opt_Cmd eq "client-delete") { cmd_client_delete(); } elsif ($Opt_Cmd eq "get") { die "%Error: Use 'c4 update' instead of 'c4 get'.\n"; } elsif ($Opt_Cmd eq "update") { if (is_c4_managed()) { cmd_update(); } else { die "%Error: Client is not under c4 management.\n"; } } elsif ($Opt_Cmd eq "unknown") { cmd_unknown(); } elsif ($Opt_Cmd eq "submit") { my %opts = P4::Getopt->hashCmd($Opt_Cmd, @Opt_CmdParams); if (!$opts{-p4} && is_c4_managed()) { cmd_submit(); } else { @Opt_CmdParams = P4::Getopt->stripOneArg('-p4',@Opt_CmdParams); cmd_p4(); } } elsif ($Opt_Cmd eq "sync") { my %opts = P4::Getopt->hashCmd($Opt_Cmd, @Opt_CmdParams); if (!$opts{-p4} && is_c4_managed()) { die "%Error: Client is under c4 management, use 'c4 update' instead of 'c4 sync'.\n"; # Or, use -p4 switch } else { @Opt_CmdParams = P4::Getopt->stripOneArg('-p4',@Opt_CmdParams); cmd_p4(); } } elsif ($Opt_Cmd eq "help-summary") { print "All commands:\n"; cmd_help_summary(); } elsif ($Opt_Cmd eq "help") { if ($#Opt_CmdParams < 0) { print "C4 Wrapper commands:\n"; print "\tc4 --help\n"; print "\tc4 help-summary\n"; print "\tc4 change-max\n"; print "\tc4 client-create -t