#!/usr/bin/perl # $Id: //depot/cad/tools/1.0/icp4-1.1/bin/p4ci#31 $ # # CSWITCH CORPORATION CONFIDENTIAL PROPRIETARY # # This file contains information which is the # proprietary property of Cswitch Corporation. # This file is confidential and its contents may # not be disclosed without the expressed written # consent of Cswitch Corporation. # For each cell given: # error check # make list of cells to add/submit # bring up edit page # Do together: # revert -a # add # submit use strict; use warnings; use FindBin qw($Bin); use lib "$Bin/../lib"; use Icp4; use Getopt::Std; use File::Basename; use Cwd; our ($Program, %opt, $islayout, $nflag, $rflag, $client, $cells, $support); our $attr_sfx = ".Ic_cell_template.attr"; our $cell_sfx = ".iccel_[0-9]+"; our $keep = 1; # each file in raw_list has a file status: # raw # edit # add # revert our %file_status; our @raw_list; our @revert_list; our @add_list; our @edit_list; our @user_add_list; our @user_edit_list; # turn on logging of p4ci to ~/p4ci.log my $P4CI_LOG = 1; #my $P4CI_LOG = 0; MAIN: { $Program = $FindBin::Script; getopts('hDnirk:', \%opt); if ($opt{h} || $#ARGV < 0) { print "Usage: $Program [-h] [-n] [-i] [-k num] [-r] cell+\n"; print " -h: help usage\n"; print " -n: show operation only\n"; print " -i: ignore pending changes (dangerous!)\n"; print " -k: number of versions to keep\n"; print " (default: $keep, works for layout only for now)\n"; print " -r: remain open for edit after checkin\n"; print " (default: locked after checkin)\n"; print " cell: cell name(s)\n"; print " (hint: use \\\$ for cells with \$ character in their name)\n"; exit 0; } $nflag = ($opt{n}) ? "-n" : "" ; $rflag = ($opt{r}) ? "-r" : "" ; $keep = $opt{k} if ($opt{k}); #$Icp4::debug = ($opt{D}) ? 1 : 0 ; # keep Icp4 quiet $Icp4::debug = 0; $Icp4::nflag = ($opt{n}) ? 1 : 0 ; # make sure p4 is configured if (&Icp4::where() eq 'error') { print "ERROR: Current directory not in client. Please check P4 variables.\n"; exit -1; } $client = &Icp4::p4client(); $support = "ryu\@cswitch.com"; # check for outstanding changes if (!$opt{i} && &Icp4::outstanding_changes()) { exit -1; } if ($islayout = &Icp4::is_layout_view()) { # At this point, the raw_list contains only attr and iccel files # that are known to exist in unix. get_raw_list(); if ($opt{D}) { &Icp4::list_debug_print("raw_list", @raw_list); } # revert list is a subset of raw_list and are files that have not been modified get_revert_list(); if ($opt{D}) { &Icp4::list_debug_print("revert_list", @revert_list); } # edit list is a subset of raw_list and are files that have been modified get_edit_list(); if ($opt{D}) { &Icp4::list_debug_print("edit_list", @edit_list); } # add list is a subset of raw_list and new files to p4 get_add_list(); if ($opt{D}) { &Icp4::list_debug_print("add_list", @add_list); } # Bring up the form. all files listed will be # reverted if not changed, added if it's new, and then submitted. p4_add_submit_revert(); } else { old_p4ci(); } exit 0; } sub get_raw_list { my ($cell, $orig_cell, $path); my ($attr_file, $orig_attr_file, $ic_pat, $ic_file); my ($openStat, $expectedStat); my (@keep_list, $i, $s, $orig_cnt, $exists); $cells = ""; foreach $cell (@ARGV) { # get rid of any trailing "/" and convert to full path $cell =~ s/\/$//; $path = Cwd::abs_path(dirname($cell)); $orig_cell = $cell; # escape the name for p4 if ($cell =~ /\$/) { $cell =~ s/\$/\\\$/g; if ($opt{D}) { print "# DEBUG: path = $path\n"; print "# DEBUG: cell = $cell\n"; print "# DEBUG: orig_cell = $orig_cell\n"; } } if (-d $orig_cell) { # remove any .iclck files unlink <${orig_cell}/.*.iclck>; $cells = $cells . "${cell}/... "; #$cell_attr = $cell . $attr_sfx; $ic_pat = $cell . $cell_sfx; $orig_attr_file = "${orig_cell}/${orig_cell}${attr_sfx}"; $attr_file = "${cell}/${cell}${attr_sfx}"; if (has_lckfiles($cell)) { print "WARNING: Cell \"$cell\" is locked by icstudio. Skipping cell \"$cell\".\n"; next; } # workaround for some attribute files that have .s if (! -f "$orig_attr_file") { print "WARNING: $orig_attr_file not found. Trying the .s trick.\n"; $orig_attr_file = "${orig_cell}/${orig_cell}.s${attr_sfx}"; $attr_file = "${cell}/${cell}.s${attr_sfx}"; if (! -f "$orig_attr_file") { print "WARNING: $orig_attr_file not found either. Skipping \"$orig_cell\".\n"; next; } else { print "INFO: Found $orig_attr_file.\n"; } } &Icp4::get_keep_list($orig_attr_file, \@keep_list); if ($opt{D}) { &Icp4::list_debug_print("keep_list", @keep_list); } $orig_cnt = $#keep_list; for ($i=0; $i <= ($orig_cnt - $keep); $i++) { shift @keep_list; } if ($opt{D}) { print "# DEBUG: After trimming ... $#keep_list\n"; &Icp4::list_debug_print("keep_list", @keep_list); } # existence check for @keep_list files $exists = 1; foreach $i (@keep_list) { $ic_file = "$path/$orig_cell/$i"; if (! -f $ic_file) { $exists = 0; print "ERROR: \"$ic_file\" not found. Skipping cell \"$cell\".\n"; last; } } if ($exists) { $s = "${path}/${orig_attr_file}"; push (@raw_list, $s); $file_status{$s} = "raw"; foreach $i (@keep_list) { $s = "${path}/${orig_cell}/$i"; push (@raw_list, $s); $file_status{$s} = "raw"; } } } } close FOUT; } sub get_revert_list { my($rawfile) = ".rawlist.$$"; my ($s); open (FOUT, ">$rawfile") or die "ERROR: cannot open $rawfile."; foreach $s (@raw_list) { print FOUT "$s\n"; } close FOUT; open (REVERT, "p4 -x $rawfile revert -a -n 2>&1 |") or die "ERROR: cannot run p4 revert."; while () { if (($s) = /(.*)#\d+ - was edit, reverted/) { # change name $s =~ s#//depot#$client#; push (@revert_list, $s); if ($file_status{$s}) { $file_status{$s} = "revert"; } else { die "INTERNAL ERROR: file status of $s not found. Please notify $support.\n"; } } } close REVERT; unlink $rawfile unless ($opt{D}); } sub get_edit_list { my (%p4files) = Icp4::fstat(@raw_list); my ($s); @edit_list = (); foreach $s (sort keys %p4files) { # print "# DEBUG: file \"$s\" has p4 status \"$p4files{$s}\".\n" if ($opt{D}); if ($p4files{$s} eq 'edit') { if ($file_status{$s}) { if ($file_status{$s} ne 'revert') { push (@edit_list, $s); $file_status{$s} = "edit"; } } else { die "INTERNAL ERROR: file status of \"$s\" not found during get_edit_list. Please notify $support.\n"; } } } } sub get_add_list { my (%p4files) = Icp4::fstat(@raw_list); my ($s); @add_list = (); foreach $s (sort keys %p4files) { if (($p4files{$s} eq '???') || ($p4files{$s} eq 'delete')) { if ($file_status{$s}) { push (@add_list, $s); $file_status{$s} = "add"; } else { die "INTERNAL ERROR: file status of \"$s\" not found during get_add_list. Please notify $support.\n"; } } } } sub p4_add_submit_revert { my($file, $editor); my($proceed); my($extract); my($list_ptr, $s, $type, $depot_file); # create a changelist by combining list of opened # files with changelist template my($template) = ".template.$$"; my($changelist) = ".changelist.$$"; system("p4 change -o > $template"); # When a workspace has nothing opened, the $template file will have no "Files:" line # Add it to the bottom of the file David Guan my($cnt); chop($cnt = `egrep -c Files $template`); if ($cnt == 1) { system("echo 'Files:' >> $template"); } open (TEMPLATE, "$template") or die "ERROR: cannot open $template."; open (CHANGELIST, ">$changelist") or die "ERROR: cannot open $changelist."; while (