p4users.pl #1

  • //
  • guest/
  • sandy_currier/
  • utils/
  • p4users.pl
  • View
  • Commits
  • Open Download .zip Download (6 KB)
eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
  & eval 'exec perl -S $0 $argv:q'
  if 0;
#  THE PRECEEDING STUFF EXECS perl via $PATH
#
# $Id: //guest/sandy_currier/utils/p4users.pl#1 $
#

#
# Copyright (c) 2000, Sandy Currier (sandy@releng.com)
# Distributed under the GNU GENERAL PUBLIC LICENSE:
#
#      This program is free software; you can redistribute it and/or modify
#      it under the terms of the GNU General Public License as published by
#      the Free Software Foundation; either version 1, or (at your option)
#      any later version.
#
#      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 GNU General Public License
#      along with this program; if not, write to the Free Software Foundation,
#      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#

#
# Unbuffer STDERR and STDOUT
select(STDERR);
$| = 1;			# Make STDERR be unbuffered.
select(STDOUT);
$| = 1;			# STDOUT too

#
# set up some globals
$ThisCmd = "p4users"; # this command name

#
# local variables
$P4 = "p4";
$verbose = 0;
$err = "***";

#
# now parse any args
# the usage message (for -h or on error)
$help = "$ThisCmd
Function:
    $ThisCmd will list the users catalogued in the various perforce
    groups as well as those perforce groups.  Will follow subgroups
    links.  Will also print <UNKNOWN> for those users listed in a
    group but who have never logged into the server.
                      
Switches/Options:
    -h              Prints this help message
    -u              Only print 'UNKNOWN' users (see above)
";

#
# parse command line
{
    my($i) = 0;
    while($i <= $#ARGV) {
	# scan for a help switch
	if ($ARGV[$i] =~ /^-h/i) {
	    &DieHelp("", $help);
	}
	# scan for switches
	elsif ($ARGV[$i] =~ /^-n/i) {
	    $printonly = 1;
	    $i++;
	}
	elsif ($ARGV[$i] =~ /^-u/i) {
	    $unknown = 1;
	    $i++;
	}
	# scan for variable definitions (-variable value)
	elsif ($ARGV[$i] =~ /^-\w+/ and defined($ARGV[$i+1]) and $ARGV[$i+1] !~ /^-[^-]/) {
	    # NOTE: nt has a difficult time with '=' on a command line...
	    # process any variable value switches
	    my($var) = $ARGV[$i];
	    $var =~ s/^-//;
	    my($value) = $ARGV[$i+1];
	    if (defined $$var) {
		$$var = $value;
	    }
	    else {
		&DieHelp("Unknown parameter '$var'\n", $help);
	    }
	    $i=$i+2;
	}
	# catch unsupported switches
	elsif ($ARGV[$i] =~ /^-/) {
	    &DieHelp("Unsupported switch \"$ARGV[$i]\"\n", $help);
	}
	else {
	    &DieHelp("Unsupported argument \"$ARGV[$i]\"\n", $help);
	}
    }
}

#
# first, list the groups
@Groups = &ExecuteP4Cmd("$P4 groups", $verbose);
chomp(@Groups);

#
# get the group info, collecting user and subgroups
foreach my $group (@Groups) {
    &GetGroupInfo($group, \%GroupInfo);
}

#
# now, create a hash for each user found, and add up all the group info
foreach my $group (@Groups) {
    # for each top level group, only visit the subgroups once
    # use a local instead of a my for proper scoping
    local @Visited;
    &GetUsers($group, $group);
}

#
# now get the real p4 user output
@Users = &ExecuteP4Cmd("$P4 users", $verbose);
chomp(@Users);
# make an array of just the user names for easy grep'ing
foreach (@Users) {
    /^(\S+)\s+</;
    push @Usernames, $1;
}

#
# now print stuff
foreach my $user (sort(keys(%Users))) {
    my $tmp = join(', ', sort(@{$Users{$user}}));
    my $foo = grep(/^$user$/, @Usernames);
    if ($foo) {
	printf STDOUT "%-20s%s\n", $user, $tmp unless ($unknown);
    }
    else {
	printf STDOUT "%-20s%s   <UNKNOWN>\n", $user, $tmp;
    }
}

#
# the end
exit(0);

#
# subroutines
#

# for the specified group, set the hash with the values
sub GetGroupInfo {
    my($group, $groupinfo) = @_;
    my($sub_p, $users_p);
    my(@output) = &ExecuteP4Cmd("$P4 group -o $group", $verbose);
    chomp(@output);
    foreach my $line (@output) {
	if ($line =~ /^MaxResults:\s+(\S+)/) {
	    $$groupinfo{$group}{'MaxResults'} = $1;
	}
	elsif ($line =~ /^Subgroups:/) {
	    $sub_p++;
	}
	elsif ($sub_p and $line =~ /^\s+(\S+)/) {
	    push @{$$groupinfo{$group}{'Subgroups'}}, $1;
	}
	elsif ($sub_p and $line eq "") {
	    $sub_p = 0;
	}
	elsif ($line =~ /^Users:/) {
	    $users_p++;
	}
	elsif ($users_p and $line =~ /^\s+(\S+)/) {
	    push @{$$groupinfo{$group}{'Users'}}, $1;
	}
    }
}


sub GetUsers {
    my($group, $subgroup) = @_;
    # loop over explicit users and add info
    foreach my $user (@{$GroupInfo{$subgroup}{'Users'}}) {
	if (!grep(/^$group$/, @{$Users{$user}})) {
	    push @{$Users{$user}}, $group;
	}
    }
    # loop over subgroups if they have not been visited yet
    foreach my $subg (@{$GroupInfo{$subgroup}{'Subgroups'}}) {
	if (!grep(/^$subg$/, @Visited)) {
	    # this subgroup has not been visited yet - must visit it
	    &GetUsers($group, $subg);
	    # add this subgroup to the visited list
	    push @Visited, $subg;
	}
	else {
	    # this subgroup has already been visited - just return
	}
    }
}


sub DieHelp {
    my($str, $help) = @_;
    print STDERR "$err $str\nUsage: $help";
    exit(1);
}


#
# Note: this will actually execute any command...
# returns the action of the revision of the specified file#revision
sub ExecuteP4Cmd {
    my($script, $verbose, $print_output, $no_error_check, $stream_p) = @_;
    my(@output);
    if ($stream_p) {
	print $stream_p "$vb\n$vb running: $script\n$vb\n" if ($verbose);
    }
    else {
	print STDOUT "$vb\n$vb running: $script\n$vb\n" if ($verbose);
    }
    if (!$Platform{'nt'} and $Platform{'os'} eq "win32") {
	@output = `$script` unless ($printonly);
    }
    else {
	@output = `$script 2>&1` unless ($printonly);
    }
    if ($stream_p) {
	print $stream_p "@output" if ($print_output);
    } else {
	print STDOUT "@output" if ($print_output);
    }
    if (!$no_error_check and $?) {
	# now what - just keep going
	print STDERR "$err $ThisCmd - something happened with '$script'\n$?";
    }
    return(@output);
}
# Change User Description Committed
#5 6452 sandy_currier cleaning up some defunct and out-of-date stuff
#4 912 sandy_currier these versions should all be xtext only
#3 548 sandy_currier updating various versions of these scripts
#2 368 sandy_currier another update of these guys
#1 316 sandy_currier might as well add yet another G.P.L.'ed script at this point