Perforce Training, 2010.1

Scripting Perforce

Introduction

• Introductions

• Class Schedule

• About the Exercises

1 Perforce Training, 2010.1

Intended course audience

• Experienced Perforce users need to scripts

• Configuration management, build, and release engineers, and others

Prerequisite experience

• PfPerforce user and ddiitt administrator

• Writing scripts using Perl

2 Perforce Training, 2010.1

Objectives

• DlDevelop scr ittfipts to perform common t tkasks

• Follow best practices

Uses of scripts

• Web browser interface to Perforce • Plug-in for an IDE • Back-up and recovery routines • Wrappers for Perforce commands • Customized d iff a nd me rge tool s • Conversion from other SCM tools

3 Perforce Training, 2010.1

Script examples in this course

• Automating processes • Generating reports • Sending email • Process support • Auditing metadata

Course Contents

• Preliminary Decisions • Perforce Commands for Scripting • Line Program (p4) • Application Program Interface (API) • Daemons • TiTriggers • Wrappers and Administrative Scripts

4 Perforce Training, 2010.1

Preliminary Decisions

• Setting Environment Variables

• User Authentication

• Client Program Interface

Preliminary Decisions

Setting Environment Variables

5 Perforce Training, 2010.1

Use global options

• Set environment variables in script p4 –p serverport –u username info

• Advantage: Overrides all other settings

• Disadvantage: Edit each script to change

Use configuration files

• Set P4CONFIG to a name p4 set P4CONFIG=config.txt

• Place config.txt files in script folders

• List environment variables in config.txt P4PORT=lemon:1909 P4CLIENT=script_user_reporter P4USER=script_user

6 Perforce Training, 2010.1

P4CONFIG example : P4CONFIG=config.txt

C:\scripts

P4PORT=krypton:1666 P4CLIENT=scriptuser-prod config.txt P4USER=scriptuser

\Krypton

P4PORT=xenon:1666 P4CLIENT=report-writer config.txt P4USER=reporter

\Xenon

Using P4CONFIG

• Advantages • Configures many scripts • Active in specific directories

• Disadvantage • If P4CONFIG unset, script environment may change

7 Perforce Training, 2010.1

Use environment variables

• Set environment variables (Windows) p4 set P4PORT=p4demo.com:1666

• List environment variables p4 set P4CLIENT= br un o_o w s (set) P4PORT=p4demo.com:1666 (set) P4USER=bruno (set)

Using environment variables

• Advantaggye: Easy to set

• Disadvantages

• May be accidentally changed • Depends upon shell being used

8 Perforce Training, 2010.1

Configuration order of precedence

• Command-line flags

• P4CONFIG files • Environment variable settings • Registry variable settings (on Windows) • Default value for environment variables

Preliminary Decisions

User Authentication

9 Perforce Training, 2010.1

Use login

• Works for all server security levels

• Usage: p4 login Enter password: UitldiUser script_user logged in.

Use a group to extend session

p4 group scriptsonly Group: scriptsonly MaxResults: 100000 Maxscanrows: 500000 MaxLockTime: 30000 Timeout: unlimited Subgroups: Owners: bruno Users: script_user

10 Perforce Training, 2010.1

Use a password

• Security levels 0-2 p4 -P Script_pass users

• Security level 3 p4 login -p Enter password: 9CC3EACDEFCC8C7020C134D6D333F46F p4 -P 9CC3EACDEFCC8C7020C134D6D333F46F users

Preliminary Decisions

Client Program Interface

11 Perforce Training, 2010.1

Comparing client program interfaces

Command Line Program Apppplication Pro gram Interface p4 Perforce C/C++ API One connection per User controls connection command Returns lines of text Tagged data available

Some language support Language derivatives available Java-native API (P4Java) Objective-C API (P4ObjC)

Tagging output: Command line and API

• Command line returns lines of text

• Format output by using -ztag p4 -ztag clients ... client bruno_ws ... Update 1104271684 ... Access 1104340062 ... etc. • Perforce API supports tagged data output

12 Perforce Training, 2010.1

Command line program: bypass an editor

• Redirect to standard output p4 change -o

• Read from standard input p4 submit -i

Command line program: Using Python

• Create Python marshalled dictionary object p4 -G job -o

13 Perforce Training, 2010.1

Sample Python Script and p4 -G Output

#!/usr/local/bin/python #Example script named readmarshal.py

import marshal, sys true = 1 try: while true: vars = marshal.load(sys.stdin) print vars except EOFError: '' #note that these are two single-quotes

p4 -G user -o raj |dhl| readmarshal.py {'Email': '[email protected]', 'Update': '2005/12/06 11:16:30', 'Reviews1': '//depot/dev/main/...', 'Reviews0': '//depot/www/...', 'FullName': 'Raj Bai', 'User': 'raj', 'code': 'stat', 'Access': '2006/07/06 15:16:30'}

Command line program: Using Ruby

• Create Ruby marshalled dictionary object p4 -R job –o

14 Perforce Training, 2010.1

Sample Ruby script and p4 -R output

# Example script named readruby.rb f = IO.popen("p4 -R user -o " + ARGV[0]) user_info = Marshal.load(f) p user_info

readruby.rb bruno {"code"=>"stat", "User"=>"bruno", "Email"=>"[email protected]", "FullName"=>"Bruno Batswan"}

Perforce’s derived APIs

• P4Per l

• P4Python

• P4Ruby

15 Perforce Training, 2010.1

Scripting environment for the exercises

• Use P4CONFIG to Set Environment Variables

• User Authentication p4 login

• Client Program Interface • p4 and API (using P4Perl) examples

Scripting Perforce

Exercise Setting the Perforce Environment

16 Perforce Training, 2010.1

Scripting Perforce

Perforce Commands for Scripting

Perforce Commands for Scripting

• General

• Review Daemons

• Data Mining

17 Perforce Training, 2010.1

Perforce Commands

General

Capture errors, warnings and messages

p4 -s opened -c default error: File(s) not opened on this client. : 0

18 Perforce Training, 2010.1

Submit without invoking an editor

p4 submit -d "Fixed results of sim scans." Submitting change 1825. Locking 2 files ... edit //Sim/Prod/MAIN/src/sim.c#36 edit //Sim/Prod/MAIN/src/scan.c#2 Change 1825 submitted.

Script efficiently

• Limit number of lines of data returned

• Narrow scope of Perforce commands • Refer to known workspace spec • Access small ggproups of de pot files

19 Perforce Training, 2010.1

List a single changelist

UiUsing a c lient wor kspace name p4 changes -m1 –s submitted –c raj-spruce Change 421 on 2001/01/07 by raj@raj-spruce 'Update sim to work reasonably on'

List several changelists

Using a depot path p4 changes –m10 //depot/www/... Change 1769 on 2006/12/11 by quinn@quinn-azalea 'Copy jamgraph example to web' Change 1763 on 2006/11/23 by hera@hera-amphora 'Jamgraph 1.0 is live.' ...etc.

20 Perforce Training, 2010.1

Perforce Commands

Review Daemons

Use a counter

• Set personal counter p4 counter notifyd 746 Counter notifyd set.

• Poll a counter p4 counter notifyd 746

21 Perforce Training, 2010.1

List all counter values

p4 counters change = 750 job = 4 journal = 15 notifyd = 746 ... etc.

Review daemon tools

• View changelists past counter value p4 review -t notifydy Change 747 bruno [email protected](Bruno Batswan) Change 749 brad [email protected](Brad Manners) Change 750 sam [email protected](Sam Maxwell)

• View subscribers for email notification p4 reviews -c 747 bruno (Bruno Batswan) laura (Laura Germain)

22 Perforce Training, 2010.1

Change your user profile

p4 user

User: earl Email: [email protected] Update: 2007/08/09 13:45:59 Access: 2008/03/07 16:45:05 FullName: Earl Ashby Reviews: Add “Reviews:” field if //Sim/Prod/MAIN/... running review daemon //depot/www/...

List recently edited/created jobs

p4 jobs -e "date>=2007/06/21" job002127 on 2007/11/19 by earl *open* ‘Fix parse error’ job002097 on 2007/10/21 by raj *closed* ‘Exit off’ job001931 on 2007/10/16 by gail *punted* ‘Web style’ job001762 on 2007/07/08 by raj *closed* ‘Scan func’

23 Perforce Training, 2010.1

List fixed jobs

p4 fixes //Sim/Prod/MAIN/src/... job000001 fixed by change 55 on 1999/01/19 by earl@earl-dev job000002 fixed by change 114 on 1999/02/28 by earl@earl-dev job000003 fixed by change 114 on 1999/02/28 by earl@earl-dev job000004 fixed by change 148 on 1999/07/19 by earl@earl-dev job000004 fixed by change 132 on 1999/04/30 by earl@earl-dev ... etc.

Perforce Commands

Data Mining

24 Perforce Training, 2010.1

Report depot data

• List directories p4 dirs //depot/* //depot/Jam //depot/Jamgraph ...etc. • List files p4 files //depot/Jam/MAIN/src/... //depot/Jam/MAIN/src/Build.com#9 - edit change 839 //depot/Jam/MAIN/src/Build.mpw#3 - edit change 839 //depot/Jam/MAIN/src/command.c#12 - edit change 839 ...etc.

Gather file data as tagged output

p4 fstat execcmd.h ... depotFile //depot/Jam/MAIN/src/execcmd. h ... clientFile c:\raj\Jam\MAIN\src\execcmd.h ... isMapped ... headAction edit ... headType text ... headTime 1106848927 ... headRev 2 ... headChange 30 ... headModTime 1106847314 ... haveRev 2

25 Perforce Training, 2010.1

Report on a single file

p4 annotate -ac jam. c //depot/Jam/MAIN/src/jam.c#37 - edit change 93 (text) 1-93: /* 1-1: * Copyright 1993 Christopher Seiwald. 30-93: * Copyright 1993, 1995 Christopher Seiwald. ... etc.

Search for patterns in files p4 -a -n -F -e "/* debug */" jam.c //depot/Jam/MAIN/src/jam.c#14:114: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#13:114: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#12:114: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#11:106: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#10:106: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#9:96: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#8:96: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#6:93: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#5:93: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#4:93: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#3:93: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#2:91: 1, /* debug */ //depot/Jam/MAIN/src/jam.c#1:86: 1, /* debug */

26 Perforce Training, 2010.1

Report Perforce metadata

• Lis t a ll c lien t wor kspace specs p4 clients

• List client workspace specs by owner p4 clients –u bruno

Use -n flag to report status

p4 integrate -n -b SimMAINtoFLAT //Sim/Prod/FLAT/src/scan.c#3 sync/integrate from //Sim/Prod/MAIN/src/scan.c#12 //Sim/Prod/FLAT/src/scan.h#2 sync/integrate from //Sim/Prod/MAIN/src/scan.h#14 ...etc.

27 Perforce Training, 2010.1

Test p4 commands before writing script

• Learn data output format

• Experiment with flags • if API returns tagged data • Narrow scope of commands

Scripting Perforce

Command Line Program (p4)

28 Perforce Training, 2010.1

Module objectives

• Use p4 client program in a Perl Script • Use P4CONFIG • Capture error messages • Submit files without invoking editor • Chec k for success ful su bm it (exerc ise ) • Report results to standard output

Specifications for a submit script

• Script name is submit.pl • Create a command string • Check for opened files in default changelist • Exit if no files opened • Submit files • Check for successful submit (exercise) • Print submitted changelist

29 Perforce Training, 2010.1

Construct a p4 command string

$p4c = "script_ws"; $p4 = "C:\\p4programs\\p4";

$p4 = "$p4 -c $p4c";

Exit if no opened files in default changelist

@@$pchk = `$p4 -s opened -c default`; if ($chk[0] =~ /error: File\(s\) not opened on this client./) { print "No files in default changelist to submit."; exit; }

30 Perforce Training, 2010.1

Submit files

$desc = "An automated submit from $p4c.";

`$p4 submit -d "$desc"`;

Print submitted changelist

$chg = `$p4 changes -m1 -s submitted -c $p4c`; $chg =~ /(^Change) ([0-9]+) (.+$)/; print `$p4 describe -s $2`;

31 Perforce Training, 2010.1

Scripting Perforce

Exercise A Submit Script

Scripting Perforce

Application Program Interface (API)

32 Perforce Training, 2010.1

Module objectives

• Write a generic P4Perl script • Run a command

• Check for errors

• PdtProcess data

• Python and Ruby examples

Specifications for a simple P4Perl script

• Script name is p4template.pl • IitiliInitialize P4iP4 ins tance • Select server level compatibility • Connect • Run a command (p4 info) • Check for errors • Process data (print data) • Disconnect

33 Perforce Training, 2010.1

Initialize P4 instance

use P4;

$p4c = “script_ws";

$p4 = new P4;

$p4 Æ SetClient( $p4c );

Set server level compatibility

$p4 Æ SetApiLevel( 67 );

Perforce Knowledge Base Articles: “Perforce Protocol Levels” and “Perforce Server Levels”

34 Perforce Training, 2010.1

Set script name

$p4 Æ SetProg( “Template” );

Connect

$4$p4 Æ Connec t() or die ("Canno t connec t to server. ");

35 Perforce Training, 2010.1

Select output mode

• Tagged mode (on by default) Normally returns hash reference $p4 Æ Tagged(1);

• Standard mode Normally returns array of $p4 Æ Tagged(0);

Run a command

• General syntax $p4 Æ Run("p4command", "flags", "filespecs");

• Example

@res = $p4 Æ Run("info ");

36 Perforce Training, 2010.1

Check for errors

if ($p4 ÆErrorCount()) { @err = $p4 Æ Errors(); foreach $str(@err) { print "Error message: $str \n"; }

Check for warnings

} elsif ($p4 Æ WarningCount()) { @wrn = $p4 Æ Warnings(); foreach $str(@wrn) { print “Warning message: $str \n”; } } else { # Other data integrity checks }

37 Perforce Training, 2010.1

Process tagged data

if ($p4 ÆIsTagged()) { foreach $str(@res) { %hash = %{$str}; while (($key, $value) = each(%hash)) { pp$y$rint "$key => $value\n"; } } }

Process standard data

else { foreach $str (@res) { print ($str, "\n"); } }

38 Perforce Training, 2010.1

Disconnect

$p4 Æ Disconnect();

Scripting Perforce

Demo p4template.pl

39 Perforce Training, 2010.1

Python p4template.py

import sys, types from P4 import P4, P4Exception p4 = P4() def init(): p4.api_level = 65 p4.exception_level = 2 p4.prog = "Python Template" p4.client = "script_ws" try: p4.connect() except P4Exception: print "Cannot connect to the server." sys.exit(1)

Python function getdata

def getdata(cl): try: res = p4.run(cl) return res except P4Exception: for e in p4.errors: print "Errors: " + e p4di4.disconnec t() sys.exit(1) for w in p4.warnings: print "Warnings: " + w

40 Perforce Training, 2010.1

Python function printdata

def pp()rintdata(r): if not (isinstance(r, types.NoneType)): for i in range(len(r)): if (p4.tagged): dict = r[i] for key in dict.keys(): print "%s :: %s" % (key,dict[key]) else: print r[i]

Python MAIN program def runstub(c): data = getdata(c) printdata(data)

# MAIN PROGRAM init() p4.tagged = False cmd = "info" runstub(cmd) prit"int " \n \n" p4.tagged = True runstub(cmd)

p4.disconnect()

41 Perforce Training, 2010.1

Ruby p4template.rb

def init begin require "P4" $p4 = P4.new() p4.api_level = 65 $p4.exception_level = P4::RAISE_ALL $p4.prog = “Ruby Template" $p4.client = "script_ws" $p4.connect rescue P4Exception print "Cannot connect to the server." exit end end

Ruby method getdata

def getdata(cl) begin res = $p4.run(cl) return res rescue P4Exception $p4.errors.each { |e| puts( e ) } if not $p4.errors.empty? $p4.disconnect exit end $p4.warnings.each { |w| puts( w ) } end end

42 Perforce Training, 2010.1

Ruby method printdata

def printdata(()r) if not r.empty? if $p4.tagged? h = r[0] h.each { |k,v| puts "#{k} => #{v}"} else puts r end end end

Ruby MAIN program def runstub(c) data = getdata(c) pp()rintdata(data) end # MAIN PROGRAM init $p4.tagged = false cmd = "info" runstb(tub(cmd) print " \n \n" $p4.tagged = true runstub(cmd) $p4.disconnect

43 Perforce Training, 2010.1

Specifications for a release notes script

• Input • Depot path • Revision range • Number of changelists to process

• Output • List of changelist numbers • Description for each changelist (exercise) • List of jobs fixed (exercise)

Get a list of changelists

# Script name is relnotes. pl

# Initialize P4Perl, connect, then:

@cmd = ("changes", "-s", "submitted", "//Sim/Prod/REL2.1/src/... ");

@chg = $p4 Æ Run(@cmd);

44 Perforce Training, 2010.1

Process data

foreach $str (@chg) { %hash = %{$str}; print ($hash{"change"}, "\n"); }

Scripting Perforce

Exercise A Release Notes Script

45 Perforce Training, 2010.1

Scripting Perforce

Daemons

Daemons learning objectives

• What is a review daemon?

• How users subscribe to get email • Write a review daemon script • Use Perforce counters • Check for Perforce job updates

46 Perforce Training, 2010.1

Specifications for a review daemon

• Input • Changelists to review

• Output • Email changelist descriptions to subscribed users • Update review daemon counter

• Option • Email edited jobs to subscribed users (exercise)

Main program

# Script name is p4review. pl # Initialize P4Perl, connect then: checkcounter(); while(1) { poll_server(); ($sleeptime); }

47 Perforce Training, 2010.1

Initialize review counter

sub checkcounter { $p4 Æ Connect() or die ("Cannot connect to Perforce server."); $p4 Æ Tagged(0); @data = $p4 Æ Run("counter", "review"); $rc = @data[0]; if ($rc == 0) { $p4 Æ Run ((,,);"counter", "review", "0"); } $p4 Æ Tagged(1); $p4 Æ Disconnect(); }

Poll the server

sub poll_server { $p4 Æ Connect() or die ("Cannot connect to Perforce server." ); @data = $p4 Æ Run ("review", "-t", "review"); if ($#data > -1) { foreach $str (@data) { %hash = %{$str}; $chg = $hash{change}; revi($h)iewers($chg); } updatecounter($chg); } $p4 Æ Disconnect(); }

48 Perforce Training, 2010.1

Check for reviewers sub reviewers { ($chg) = @_ ; @cmd = ("reviews", "-c", $chg); @data = $p4 Æ Run(@cmd); if ($data[0] =~m/^HASH/) { @@(c1 = ("describe" , "-s",,$ $ch g); @des = $p4 Æ Run(@c1); sendoutmail(@des, @data); } }

Get the changelist data

sub sendoutmail { (@users) = @_; $cdes = shift(@users); foreach $str (@cdes) { %%g%{$};change = %{$str}; $chgno = $change{change}; $desc = $change{desc}; }

49 Perforce Training, 2010.1

Send out mail

foreach $str (@users) { %user = %{$str}; print "To: $user{email} \n"; print "From: daemon\@p4demo.com \n"; print "Subject: Changelist $chgno submitted. \n"; print "Description: $desc\n"; } }

Update review counter

sub updatecounter { ($chg) = @_; $p4 Æ Run ("counter", "review", $chg); }

50 Perforce Training, 2010.1

Adding updates to jobs reporting

use ::L oca l;

# create a jobreview counter # time() returns local Unix time.

$p4 Æ Run("counter "", jobreview", time());

Check for newly modified jobs sub checkforjobs { $p4 Æ Tagged(0); @data = $p4 Æ Run ("counter", "jobreview"); $p4 Æ Tagged(1); $tchk = @data[0]; @jobs = $p4 Æ Run("jobs", "-e", "date>=$tchk"); foreach $str (@jobs) { @users = jobreviewers(); sendjobemail($str, @users); } updatejobcounter(); }

51 Perforce Training, 2010.1

Check for job reviewers

sub jobreviewers { @data = $p4 Æ Run ("reviews", "//depot/jobs"); return @data; }

Additions to the review daemon script

• Add jobs to email

• Update jobreview counter

52 Perforce Training, 2010.1

Scripting Perforce

Exercise A Review Daemon

Scripting Perforce

Triggers

53 Perforce Training, 2010.1

Triggers learning objectives

• Supported trigger types in Perforce • Best practices when writing triggers • Implementing triggers • Install a “submit policy” trigger • Install a “workspace check” trigger

Supported trigger types

• Password authentication

• Changelist processing • Form manipulation or validation • Job fix adds or deletes

54 Perforce Training, 2010.1

Use triggers to enforce policy

• Authenticate passwords against an LDAP server • RELNOTES file always submitted with *.c files • Submit to “rel1” codeline fixes least one job • Add “reviewed by:” when changelist created • Evaluate edited forms for correctness • Begin a build after submit to “dev” codeline • Prevent users from deleting branch specs

Script efficiently

• Follow best practices in scripting

• Check Perforce release notes for optimizations

• Time your scri p t’s execu tion

55 Perforce Training, 2010.1

Avoid common errors

• Writing data to the server

• Recursive triggers

• Attempting workspace operations

Implementing triggers

• TtTest scri itlllpt locally

• Install on test server

• Deploy on production server

56 Perforce Training, 2010.1

Enforcing a submit policy

• Trigger name is checksubmit . pl

• Run as a change-submit trigger

• Enforce a codeline policy: edits of *.c files always include a RELNOTES file update .

Enforcing a workspace configuration policy

• Trigger name is checkworks pace. pl

• Run as a form-save trigger

• Enforce a workspace creation policy: no client workspaces can be saved with a “wide open” view e.g., //Sim/... //my_client/...

57 Perforce Training, 2010.1

Scripting Perforce

Exercise Implementing Triggers

Scripting Perforce

Wrappers and Administrative Scri ptin g

58 Perforce Training, 2010.1

Module objectives

• Modify Perforce form using P4Perl

• List unwanted user created configurations

Examples of build wrappers

• Create temporary client spec • Sync to changelist or label • Create label spec and tag files • Email users build results • Automate submit of objects

59 Perforce Training, 2010.1

Specifications for temporary client spec

• Edit a cli ent spec

• Modify options • Modify view • Save client spec

Get the client spec form

# Script name is p4client.pl

# Initialize P4Perl, connect, then:

$cl = $p4 Æ GetClient();

@data = $p4 ÆFetchClient($cl);

60 Perforce Training, 2010.1

Modify the client spec form

foreach $str(@data) { %%{$}%hash = %{$str};

$opt = "noallwrite noclobber nocompress locked nomodtime ";

$hash{Options} = $opt;

@wv = @{$hash{View}};

@wv = (" //Sim/Prod/MAIN/src/... //$cl/src/ ..." ,

"//depot/www/... //$cl/www/..."); $hash{View} = \@wv; }

Save the client spec form

$p4 Æ SaveClient( \%hash);

$p4 Æ Disconnect();

61 Perforce Training, 2010.1

Scripting Perforce

Exercise Creating a Temporary Client Spec

Sample wrapper scripts

• Add custom tools to P4V • Launch third-party tools. • Run command line commands • Get latest files based on have list • Automate routine integrations

62 Perforce Training, 2010.1

Sample administrative scripts

• Enforce branchinggp polic y • files that need merging • Back up database • Delete obsolete client workspaces • Delete obsolete labels • Ensure client specs used from single host

Specifications for a client spec abuse script

• List client specs with blank Host field

• List users who own too many client specs

63 Perforce Training, 2010.1

Main program

# Script name is clientspecabuse.pl

init(); checkforhosts();

workspacesperuser();

printdata();

Initialize

sub init { # Initialize P4Perl, connect, then: $workspacelimit = 2; }

64 Perforce Training, 2010.1

Check for Host abuse

sub checkforhosts { @cls = $p4 Æ Run("clients " ); foreach $str (@cls) { %hash = %{$str}; $h = $hash{"Host"}; $w = $hash{"client"}; if ($h e q "" ) { push (@hlist, "No Host for $w \n"); } } }

Workspaces per user

sub workspacesperuser { @u = $p4 Æ Run("users"); foreach $str (@u) { %hash = %{$str}; $un = $hash{"User"};

65 Perforce Training, 2010.1

Workspaces per user continued...

@c = $p4 Æ Run("clients", "-u", $un); if ($#c > $workspacelimit) { push (@clist, "User $un owns $#c workspaces. \n"); } } }

Print results

sub printdata { print "List of HOST abusers: \n\n"; foreach $str (@hlist) { print $str; } print “Over $workspacelimit workspaces \n\n"; foreach $str (@clist) { print $str; } }

66 Perforce Training, 2010.1

Scripting Perforce

Exercise Detecting Client Workspace Abuse

Recap of exercises

• Setting the Perforce environment • Using p4: submitting files • Using P4Perl: creating release notes • Codeline policy enforcement: triggers • Creatinggpyp a temporary client spec • Detecting client workspace abuse

67 Perforce Training, 2010.1

The End

Please fill out class evaluations.

All Perforce manuals and technical notes are available on our web page, www.perforce.com.

Report problems and get technical help from [email protected].

Share tips and ideas with other users on [email protected]

68