- <html>
- <head>
- <title>P4/Ruby - P4 class</title>
- <link rel="stylesheet" type="text/css" href="docstyle.css">
- </head>
- <body>
- <p align="right">
- <a href="index.html">Contents</a>
- </p>
- <div class="classhdr">
- <table border=0>
- <tr>
- <td>
- <span class="classtag">Class</span>
- <span class="classname">P4</span>
- <span class="classparent">< Object</span>
- </td>
- <td id="righttext">
- <span class="requiretag">require</span>
- <span class="modulename">"P4"</span>
- </td>
- </tr>
- </table>
- </div>
- <h3>Description</h3>
- Main interface to the Perforce client API. Each P4 object provides
- you with a thread-safe API level interface to Perforce. The basic
- model is to:
- <ol>
- <li>
- <a href="#new">Instantiate</a> your P4 object
- </li>
- <li>
- Specify your Perforce client environment
- <ul>
- <li><a href="#client-eq">client</a></li>
- <li><a href="#host-eq">host</a></li>
- <li><a href="#password-eq">password</a></li>
- <li><a href="#port-eq">port</a></li>
- <li><a href="#user-eq">user</a></li>
- </ul>
- </li>
- <li>
- Set any options to control output or error handling
- <ul>
- <li><a href="#exception-level-eq">exception_level</a></li>
- <li><a href="#parse_forms">parse_forms</a></li>
- <li><a href="#tagged">tagged</a></li>
- </ul>
- </li>
- <li><a href="#connect">Connect</a> to the Perforce Server</li>
- <li><a href="#run">Run</a> your Perforce commands</li>
- <li><a href="#disconnect">Disconnect</a> from the Perforce Server</li>
- </ol>
- <div class="classmethods">
- <a name="classmethods"></a>
- <h3>Class Methods</h3>
- <div class="index">
- <a href="#identify">P4.identify</a>
- <a href="#new">P4.new</a>
- </div>
- <a name="identify"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">identify</td>
- <td class="proto"><i>P4</i>.identify -> <i>aString</i></td>
- </tr>
- </table>
- </div>
- <br>
- Return the version of P4/Ruby you are using - for diagnostic purposes.
- <pre>
- ruby -rP4 -e 'puts( P4.identify )'
- </pre>
- </div>
- <a name="new"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">new</td>
- <td class="proto"><i>P4</i>.new -> <i>aP4</i></td>
- </tr>
- </table>
- </div>
- Constructs a new P4 object.
- <pre>
- p4 = P4.new()
- </pre>
- </div>
- </div>
- <div class="instancemethods">
- <h3>Instance Methods</h3>
- <div class="index">
- <table border="0">
- <tr>
- <td>
- <a href="#at_exception_level">at_exception_level</a>
- <a href="#api-eq">api=</a>
- <a href="#charset-eq">charset=</a>
- <a href="#charset-q">charset?</a>
- <a href="#client-eq">client=</a>
- <a href="#client-q">client?</a>
- <a href="#connect">connect</a>
- <a href="#cwd-eq">cwd=</a>
- <a href="#cwd-q">cwd?</a>
- <a href="#debug-eq">debug=</a>
- <a href="#delete_">delete_<spec type></a>
- <a href="#disconnect">disconnect</a>
- <a href="#errors">errors</a>
- </td>
- <td>
- <a href="#exception_level-eq">exception_level=</a>
- <a href="#exception_level-q">exception_level?</a>
- <a href="#fetch_">fetch_<spec type></a>
- <a href="#format_spec">format_spec</a>
- <a href="#host-eq">host=</a>
- <a href="#host-q">host?</a>
- <a href="#input">input</a>
- <a href="#maxresults-eq">maxresults=</a>
- <a href="#maxscanrows-eq">maxscanrows=</a>
- <a href="#output">output</a>
- <a href="#parse_forms">parse_forms</a>
- <a href="#parse_spec">parse_spec</a>
- <a href="#password-eq">password=</a>
- </td>
- <td>
- <a href="#password-q">password?</a>
- <a href="#prog-eq">prog=</a>
- <a href="#port-eq">port=</a>
- <a href="#port-q">port?</a>
- <a href="#run">run</a>
- <a href="#run_filelog">run_filelog</a>
- <a href="#run_password">run_password</a>
- <a href="#run_resolve">run_resolve</a>
- <a href="#save_">save_<spec type></a>
- <a href="#tagged">tagged</a>
- <a href="#user-eq">user=</a>
- <a href="#user-q">user?</a>
- <a href="#warnings">warnings</a>
- </td>
- </tr>
- </table>
- </div>
- <a name="at_exception_level"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">at_exception_level</td>
- <td class="proto">
- <i>p4</i>.at_exception_level( lev ) { ... } -> <i>self</i>
- </td>
- </tr>
- </table>
- </div>
- Executes the associated block under a specific exception level. Returns
- to the previous exception level when the block returns.
- <pre>
- p4 = P4.new
- p4.client = "www"
- p4.connect
- p4.at_exception_level( P4::RAISE_ERRORS ) do
- p4.run_sync
- end
- p4.disconnect
- </pre>
- </div>
- <a name="api-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">api=</td>
- <td class="proto">
- <i>p4</i>.api=<i>integer</i> -> <i>self</i>
- </td>
- </tr>
- </table>
- </div>
- <p>
- Sets the API compatibility level desired. This is useful when writing
- scripts using Perforce commands that do not yet support tagged output.
- In these cases, upgrading to a later server that supports tagged
- output for the commands in question can break your script. Using this
- method allows you to lock your script to the output format of an
- older Perforce release and facilitate seamless upgrades. Note that
- this method <b>must</b> be called prior to calling
- <span class="inlinecode">P4#connect</span>.
- </p>
- <p>
- See the Perforce
- <a href="http://www.perforce.com/perforce/technical.html#releasenotes">C/C++ API Release Notes</a>
- for the API integer levels that correspond to each Perforce release.
- </p>
- <pre>
- p4 = P4.new
- p4.api = 57 # Lock to 2005.1 format
- p4.connect
- ...
- </pre>
- </div>
- <a name="charset-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">charset=</td>
- <td class="proto">
- <i>p4</i>.charset = <i>aString</i> -> <i>aBool</i>
- </td>
- </tr>
- </table>
- </div>
- Sets the character set to use when connected to a Unicode enabled
- server. Should not be used when working with non-Unicode-enabled
- servers. Returns true if the charset was valid and returns false
- or raises a P4Exception (at exception level P4::RAISE_ERRORS or
- higher) if the charset is invalid. [Note: some versions of Ruby
- seem not to honour the boolean return value and return the charset
- string instead. This appears to be a bug in Ruby]
- <pre>
- p4 = P4.new
- p4.client = "www"
- p4.charset = "iso8859-1"
- p4.connect
- p4.run_sync
- p4.disconnect
- </pre>
- </div>
- <a name="charset-q"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">charset?</td>
- <td class="proto">
- <i>p4</i>.charset? -> <i>aString</i>
- </td>
- </tr>
- </table>
- </div>
- Get the name of the character set in use when working with
- Unicode-enabled servers.
- <pre>
- p4 = P4.new
- p4.charset = "utf8"
- p4.charset?
- </pre>
- </div>
- <a name="client-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">client=</td>
- <td class="proto">
- <i>p4</i>.client = <i>aString</i> -> true
- </td>
- </tr>
- </table>
- </div>
- Set the name of the clientspec you wish to use. If not called, defaults
- to the value of P4CLIENT taken from any P4CONFIG file present, or from
- the environment as per the usual Perforce convention. Must be called
- before you connect.
- <pre>
- p4 = P4.new
- p4.client = "www"
- p4.connect
- p4.run_sync
- p4.disconnect
- </pre>
- </div>
- <a name="client-q"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">client?</td>
- <td class="proto">
- <i>p4</i>.client? -> <i>aString</i>
- </td>
- </tr>
- </table>
- </div>
- Get the name of the Perforce client currently in use
- <pre>
- p4 = P4.new
- puts( p4.client? )
- </pre>
- </div>
- <a name="connect"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">connect</td>
- <td class="proto">
- <i>p4</i>.connect -> <i>aBool</i>
- </td>
- </tr>
- </table>
- </div>
- Connect to the Perforce Server. You must connect before you can
- execute commands. Raises a P4Exception if the connection attempt
- fails.
- <pre>
- p4 = P4.new
- p4.connect
- </pre>
- </div>
- <a name="cwd-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">cwd=</td>
- <td class="proto">
- <i>p4</i>.cwd = <i>aString</i> -> true
- </td>
- </tr>
- </table>
- </div>
- Sets the current working directory. Can be called prior to executing
- any Perforce command. Sometimes necessary if your script executes a
- chdir() as part of its processing.
- <pre>
- p4 = P4.new
- p4.cwd = "/home/tony"
- </pre>
- </div>
- <a name="cwd-q"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">cwd?</td>
- <td class="proto">
- <i>p4</i>.cwd? -> <i>aString</i>
- </td>
- </tr>
- </table>
- </div>
- Get the current working directory
- <pre>
- p4 = P4.new
- puts( p4.cwd? )
- </pre>
- </div>
- <a name="debug-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">debug=</td>
- <td class="proto">
- <i>p4</i>.debug = <i>aNumber</i> -> true
- </td>
- </tr>
- </table>
- </div>
- Set debug level. Debug output is written to $stderr. Debug levels are:
- <div class="itemdesc">
- <div>0: No debug output (default)</div>
- <div>1: Log connect/disconnect and command execution</div>
- <div>2: Log user interface function callbacks</div>
- <div>3: Log data</div>
- <div>4: Log Ruby garbage collection</div>
- </div>
- Note that levels are cumulative so level 3 includes levels 2 and 1.
- <pre>
- p4 = P4.new
- p4.debug = 1
- p4.connect
- p4.run_sync
- p4.disconnect
- </pre>
- </div>
- <a name="delete_"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">delete_<spec type></td>
- <td class="proto">
- <i>p4</i>.delete_<spec type>( [options], name ) -> <i>anArray</i>
- </td>
- </tr>
- </table>
- </div>
- The delete_* methods are simply shortcut methods that allow you to quickly
- delete the definitions of clients, labels, branches, etc. They're
- equivalent to
- <span class="inlinecode">
- p4.run( <spec type>, '-d', [options], <spec name> ).shift
- </span>
- <pre>
- require "P4"
- require "parsedate"
- include ParseDate
- now = Time.now
- p4 = P4.new
- begin
- p4.connect
- p4.run_clients.each do
- |client|
- atime = parsedate( client[ "AccessDate" ] )
- if( (atime + 24 * 3600 * 365 ) < now )
- p4.delete_client( '-f', client[ "Client" ] )
- end
- end
- rescue P4Exception
- p4.errors.each { |e| puts( e ) }
- ensure
- p4.disconnect
- end
- </pre>
- </div>
- <a name="disconnect"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">disconnect</td>
- <td class="proto">
- <i>p4</i>.disconnect -> true
- </td>
- </tr>
- </table>
- </div>
- Disconnect from the Perforce Server.
- <pre>
- p4 = P4.new
- p4.connect
- p4.disconnect
- </pre>
- </div>
- <a name="errors"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">errors</td>
- <td class="proto">
- <i>p4</i>.errors -> <i>anArray</i>
- </td>
- </tr>
- </table>
- </div>
- Returns the array of errors which occurred during execution of the
- previous command.
- <pre>
- p4 = P4.new
- begin
- p4.connect
- p4.exception_level( P4::RAISE_ERRORS ) # to ignore "File(s) up-to-date"
- p4.run_sync
- rescue P4Exception
- p4.errors.each { |e| puts( e ) }
- ensure
- files = p4.output
- p4.disconnect
- end
- </pre>
- </div>
- <a name="exception_level-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">exception_level=</td>
- <td class="proto">
- <i>p4</i>.exception_level = <i>aLevel</i> -> <i>aNumber</i>
- </td>
- </tr>
- </table>
- </div>
- Configures the events which give rise to exceptions.
- <ul>
- <li>P4::RAISE_NONE -- disables all exception raising and makes the
- interface completely procedural.
- </li>
- <li>P4::RAISE_ERRORS -- causes exceptions to be raised only when errors
- are encountered.
- </li>
- <li>P4::RAISE_ALL -- causes exceptions to be raised for both errors and
- warnings. This is the default.
- </li>
- </ul>
- <pre>
- p4 = P4.new
- p4.exception_level = P4::RAISE_ERRORS
- p4.connect # P4Exception on failure
- p4.run_sync # File(s) up-to-date is a warning so
- # no exception is raised
- p4.disconnect
- </pre>
- </div>
- <a name="exception_level-q"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">exception_level?</td>
- <td class="proto">
- <i>p4</i>.exception_level? -> <i>aNumber</i>
- </td>
- </tr>
- </table>
- </div>
- Returns the current exception level.
- </div>
- <a name="fetch_"></a>
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">fetch_<spec type></td>
- <td class="proto">
- <i>p4</i>.fetch_<spec type>( [name] ) -> <i>aHash</i>
- </td>
- </tr>
- </table>
- </div>
- The fetch_* methods are simply shortcut methods that allow you to quickly
- fetch the definitions of clients, labels, branches, etc. They're
- equivalent to
- <span class="inlinecode">
- p4.run( <spec type>, '-o', ... ).shift
- </span>
- <pre>
- p4 = P4.new
- begin
- p4.connect
- client = p4.fetch_client()
- other_client = p4.fetch_client( "other" )
- label = p4.fetch_label( "somelabel" )
- rescue P4Exception
- p4.errors.each { |e| puts( e ) }
- ensure
- p4.disconnect
- end
- </pre>
- </div>
- <a name="format_spec"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">format_spec</td>
- <td class="proto">
- <i>p4</i>.format_spec( <spec type>, aHash )-> aString
- </td>
- </tr>
- </table>
- </div>
- Converts the fields in a hash containing the elements of a Perforce form
- (spec) into the familiar string reprepresentation that users know and
- love.
- <p>
- Requires <i>parse_forms()</i> mode.
- <p>
- The first argument is the type of spec to format: 'client', 'branch',
- 'label' etc. The second is the hash to parse.
- <p>
- Note that there are shortcuts available for this method.
- <pre>
- p4.format_<spec type>( hash )
- </pre>
- instead of
- <pre>
- p4.format_spec( <spec type>, hash )
- </pre>
- Where <spec type> is 'client'/'branch'/'label' etc. etc.
- </div>
- <a name="host-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">host=</td>
- <td class="proto">
- <i>p4</i>.host = <i>aString</i> -> true
- </td>
- </tr>
- </table>
- </div>
- Set the name of the current host. If not called, defaults to P4HOST
- taken from any P4CONFIG file in effect, then P4HOST in the environment
- and finally the operating system host name.
- <pre>
- p4 = P4.new
- p4.host = "perforce.smee.org"
- p4.connect
- ...
- p4.disconnect
- </pre>
- </div>
- <a name="host-q"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">host?</td>
- <td class="proto">
- <i>p4</i>.host? -> <i>aString</i>
- </td>
- </tr>
- </table>
- </div>
- Get the current hostname
- <pre>
- p4 = P4.new
- puts( p4.host? )
- </pre>
- </div>
- <a name="input"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">input</td>
- <td class="proto">
- <i>p4</i>.input( aString ) -> true or false<br>
- <i>p4</i>.input( aHash ) -> true or false<br>
- <i>p4</i>.input( anArray ) -> true or false
- </td>
- </tr>
- </table>
- </div>
- Call prior to running a command requiring input from the user. When
- the command requests input, it's the data supplied here that will be
- returned. This applies most commonly to commands of the form
- <span class="inlinecode">"p4 cmd -i"</span>. Note that typically
- commands of that form are invoked using the
- <span class="inlinecode"><a href="#save_">P4#save_*</a></span>
- methods which call
- <span class="inlinecode">P4#input()</span> internally. So there is no need
- to call this method when using the <span class="inlinecode">save_*</span>
- shortcuts.
- <br><br>
- You may pass a string, a hash or (for commands that take multiple inputs
- from the user) an array of strings/hashes. You may only pass hashes
- when working in <span class="inlinecode">parse_forms</span> mode. If you
- pass an array, note that the array will be 'shifted' each time Perforce
- asks the user for input.
- <pre>
- p4 = P4.new
- p4.parse_forms
- p4.connect
- change = p4.run_change( "-o" ).shift
- change[ "Description" ] = "Autosubmitted changelist"
- p4.input( change )
- p4.run_submit( "-i" )
- p4.disconnect
- </pre>
- Note that <span class="inlinecode">P4#input</span> cannot predict
- whether or not the supplied input will be acceptable to the next
- command the user runs so it always returns true - regardless of the
- validity of the input.
- </div>
- <a name="maxresults-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">maxresults=</td>
- <td class="proto">
- <i>p4</i>.maxresults = <i>aNumber</i> -> <i>aNumber</i>
- </td>
- </tr>
- </table>
- </div>
- Limit the number of results Perforce will permit for subsequent
- commands. Commands that produce more than this number of results will
- be aborted. The limit remains in force until you disable it by setting
- it to zero. See <span class="inlinecode">p4 help maxresults</span> for
- information on the commands that support this limit.
- <pre>
- p4 = P4.new
- begin
- p4.connect
- p4.maxresults = 100
- files = p4.run_sync
- rescue P4Exception => ex
- p4.errors.each { |e| $stderr.puts( e ) }
- ensure
- p4.disconnect
- end
- </pre>
- </div>
- <a name="maxscanrows-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">maxscanrows=</td>
- <td class="proto">
- <i>p4</i>.maxscanrows = <i>aNumber</i> -> <i>aNumber</i>
- </td>
- </tr>
- </table>
- </div>
- Limit the number of database records Perforce will scan for subsequent
- commands. Commands that attempt to scan more than this number of
- records will be aborted. The limit remains in force until you disable
- it by setting it to zero. See
- <span class="inlinecode">p4 help maxresults</span> for
- information on the commands that support this limit.
- <pre>
- p4 = P4.new
- begin
- p4.connect
- p4.maxscanrows = 100
- files = p4.run_sync
- rescue P4Exception => ex
- p4.errors.each { |e| $stderr.puts( e ) }
- ensure
- p4.disconnect
- end
- </pre>
- </div>
- <a name="output"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">output</td>
- <td class="proto">
- <i>p4</i>.output -> <i>anArray</i>
- </td>
- </tr>
- </table>
- </div>
- Get the results of the previous command. Returns an array
- containing the output of the command. Useful in a rescue block when a
- command has partially worked, and you still need to look at the command
- output.
- <pre>
- p4 = P4.new
- begin
- p4.connect
- p4.exception_level( P4::RAISE_ERRORS ) # to ignore "File(s) up-to-date"
- files = p4.run_sync
- rescue P4Exception => ex
- files = p4.output
- if files.length
- puts( "Sync succeeded with errors" )
- else
- puts( "Sync failed!" )
- end
- ensure
- p4.disconnect
- end
- </pre>
- </div>
- <a name="parse_forms"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">parse_forms</td>
- <td class="proto">
- <i>p4</i>.parse_forms -> true
- </td>
- </tr>
- </table>
- </div>
- Extends the capabilities of tagged output to include Perforce forms. Forms
- returned by Perforce in response to commands such as "p4 client -o" will
- be parsed and returned to the caller as a Ruby hash containing keys for
- each of the fields on the form. Where a form element may contain more
- than one value, the hash value is an array containing the form elements.
- <span class="inlinecode">parse_forms</span> implies the use of
- <span class="inlinecode">tagged</span>.
- <pre>
- p4 = P4.new
- p4.parse_forms
- p4.connect
- clientspec = p4.run_client( "-o" ).shift
- puts( clientspec[ "Options" ] )
- p4.disconnect
- </pre>
- Such parsed forms are also acceptable as input to commands of the form
- <span class="inlinecode">"p4 XXXX -i"</span>. For example, to change
- the root of a clientspec you could use:
- <pre>
- p4 = P4.new
- p4.parse_forms
- p4.connect
- spec = p4.run_client( "-o" ).shift
- spec[ "Root" ] = "/home/my/new/root"
- p4.input( spec )
- p4.run_client( "-i" )
- p4.disconnect
- </pre>
- </div>
- <a name="parse_spec"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">parse_spec</td>
- <td class="proto">
- <i>p4</i>.parse_spec( <spec type>, aString )-> aHash
- </td>
- </tr>
- </table>
- </div>
- Parses a Perforce form (spec) in text form into a Ruby hash using the
- spec definition obtained from the server. Requires <i>parse_forms()</i>
- mode.
- <p>
- The first argument is the type of spec to parse: "client", "branch",
- "label" etc. The second is the raw buffer to parse.
- <p>
- Note that there are shortcuts available for this method.
- <pre>
- p4.parse_<spec type>( buf )
- </pre>
- instead of
- <pre>
- p4.parse_spec( <spec type>, buf )
- </pre>
- Where <spec type> is 'client'/'branch'/'label' etc. etc.
- </div>
- <a name="password-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">password=</td>
- <td class="proto">
- <i>p4</i>.password = <i>aString</i> -> true
- </td>
- </tr>
- </table>
- </div>
- Set your Perforce password, in plain text. If not used, takes the value of
- P4PASSWD from any P4CONFIG file in effect, or from the environment
- according to the normal Perforce conventions. This password will also be
- used if you later call <span class="inlinecode">p4.run_login</span> to
- login using the 2003.2 and later ticket system.
- <pre>
- p4 = P4.new
- p4.password = "mypass"
- p4.connect
- p4.run_login
- </pre>
- </div>
- <a name="password-q"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">password?</td>
- <td class="proto">
- <i>p4</i>.password? -> <i>aString</i>
- </td>
- </tr>
- </table>
- </div>
- Get the current password. This may be the password in plain text, or if
- you've used <span class="inlinecode">p4.run_login</span>, it'll be the
- value of the ticket you've been allocated by the server.
- <pre>
- p4 = P4.new
- puts( p4.password? )
- </pre>
- </div>
- <a name="prog-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">prog=</td>
- <td class="proto">
- <i>p4</i>.prog = <i>aString</i> -> true
- </td>
- </tr>
- </table>
- </div>
- Set the name of your 'program'. This value is visible to Perforce
- system administrators running
- <span class="inlinecode">'p4 monitor show -e'</span>
- in Perforce 2004.2 or later releases.
- <pre>
- p4 = P4.new
- p4.prog = "sync-script"
- p4.connect
- ...
- p4.disconnect
- </pre>
- </div>
- <a name="port-eq"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">port=</td>
- <td class="proto">
- <i>p4</i>.port = <i>aString</i> -> true
- </td>
- </tr>
- </table>
- </div>
- Set the host and port address of the Perforce server you want to
- connect to. If not called, defaults to the value of P4PORT in any
- P4CONFIG file in effect and then to the value of P4PORT taken from the
- environment.
- <pre>
- p4 = P4.new
- p4.port = "localhost:1666"
- p4.connect
- ...
- p4.disconnect
- </pre>
- </div>
- <a name="port-q"></a>
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">port?</td>
- <td class="proto">
- <i>p4</i>.port? -> <i>aString</i>
- </td>
- </tr>
- </table>
- </div>
- Get the address of the current Perforce server.
- <pre>
- p4 = P4.new
- puts( p4.port? )
- </pre>
- </div>
- <a name="run">
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">run</td>
- <td class="proto">
- <i>p4</i>.run( <i>aCommand</i>, <i>arguments...</i> ) -> <i>anArray</i>
- </td>
- </tr>
- </table>
- </div>
- Base interface to all the run methods in this API. Runs the specified
- Perforce command with the arguments supplied. Arguments may be in
- any form you like as long as it responds nicely to
- <span class="inlinecode">to_s</span>.
- <p>
- If the command succeeds without errors or warnings, then run returns
- an array of results. Whether the elements of the array are strings or
- hashes depends on (a) the command executed and (b) whether
- <span class="inlinecode">tagged()</span> or
- <span class="inlinecode">parse_forms()</span> have been called.
- <p>
- The array that is returned is equivalent to that returned by
- <span class="inlinecode">p4.output</span>.
- <p>
- In the event of errors or warnings, and depending on the exception level
- in force at the time, run will raise a P4Exception. If the current
- exception level is below the threshold for the error/warning, then run
- returns the output as normal and the caller must explicitly review
- <span class="inlinecode">p4.errors</span> and
- <span class="inlinecode">p4.warnings</span> to check for errors or
- warnings.
- <pre>
- p4 = P4.new
- p4.connect
- spec = p4.run( "client", "-o" ).shift
- p4.disconnect
- </pre>
- Through the magic of Object#method_missing, you can save yourself some
- typing as
- <pre>
- p4.run_XXX( args )
- </pre>
- is translated into
- <pre>
- p4.run( "XXX", args )
- </pre>
- There are also some shortcuts for common commands such as editing
- Perforce forms and submitting. So this:
- <pre>
- p4 = P4.new
- p4.parse_forms
- p4.connect
- <b>clientspec = p4.run_client( "-o" ).shift</b>
- clientspec[ "Description" ] = "Build client"
- <b>p4.input( clientspec )
- p4.run_client( "-i" )</b>
- p4.disconnect
- </pre>
- May be shortened to
- <pre>
- p4 = P4.new
- p4.parse_forms
- p4.connect
- <b>clientspec = p4.fetch_client</b>
- clientspec[ "Description" ] = "Build client"
- <b>p4.save_client( clientspec )</b>
- p4.disconnect
- </pre>
- In fact, the following are equivalent:
- <p>
- <table border=1 cellpadding="10">
- <tr>
- <td>p4.delete_xxx</td>
- <td>p4.run_xxx( "-d ").shift</td>
- </tr>
- <tr>
- <td>p4.fetch_xxx</td>
- <td>p4.run_xxx( "-o ").shift</td>
- </tr>
- <tr>
- <td>p4.save_xxx( spec )</td>
- <td>p4.input( spec )<br>
- p4.run_xxx( "-i" ).shift
- </td>
- </tr>
- </table>
- <p>
- Note that the fetch_xxx methods do not return an array as typically there
- is only one result item from such commands. Accordingly, they return the
- first result element.
- <p>
- There is also a special shortcut for submitting
- <pre>
- p4 = P4.new
- p4.parse_forms
- p4.connect
- spec = p4.fetch_change
- spec[ "Description" ] = "Automated change"
- <b>p4.submit_spec( spec )</b>
- p4.disconnect
- </pre>
- </div>
- <a name="run_filelog">
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">run_filelog</td>
- <td class="proto">
- <i>p4</i>.run_filelog(<i>fileSpec</i>) -> <i>anArray</i>
- </td>
- </tr>
- </table>
- </div>
- Runs a <span class="inlinecode">p4 filelog</span> on the fileSpec
- provided and returns an array of
- <a href="P4DepotFile.html">P4DepotFile</a> results when executed in
- tagged mode. The raw output of <span class="inlinecode">p4 filelog</span>
- in tagged mode is difficult to work with so this method restructures
- the output into a more user-friendly (and object-oriented) form.
- <pre>
- p4 = P4.new
- p4.parse_forms
- begin
- p4.connect
- p4.run_filelog( "index.html" ).shift.each_revision do
- |r|
- r.each_integration do
- |i|
- # Do something
- end
- end
- rescue P4Exception
- p4.errors.each { |e| puts( e ) }
- ensure
- p4.disconnect
- end
- </pre>
- </div>
- <a name="run_password">
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">run_password</td>
- <td class="proto">
- <i>p4</i>.run_password(<i>oldpass</i>, <i>newpass</i>) -> <i>anArray</i>
- </td>
- </tr>
- </table>
- </div>
- A thin wrapper to make it easy to change your password. This method
- is (literally) equivalent to the following code:
- <pre>
- p4.input( [ <i>oldpass</i>, <i>newpass</i>, <i>newpass</i> ] )
- p4.run( "password" )
- </pre>
- For example:
- <pre>
- p4 = P4.new
- p4.password = "myoldpass"
- begin
- p4.connect
- p4.run_password( "myoldpass", "mynewpass" )
- rescue P4Exception
- p4.errors.each { |e| puts( e ) }
- ensure
- p4.disconnect
- end
- </pre>
- </div>
- <a name="run_resolve">
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">run_resolve</td>
- <td class="proto">
- <i>p4</i>.run_resolve( <i>args</i> ) [ <i>block</i> ] -> <i>anArray</i>
- </td>
- </tr>
- </table>
- </div>
- Interface to 'p4 resolve'. Without a block, simply runs a
- non-interactive resolve - typically an automatic resolve.
- <pre>
- p4.run_resolve( "-at" )
- </pre>
- <p>
- When a block is supplied, the block is invoked once for each
- merge scheduled by Perforce. For each merge, a
- <a href="P4MergeData.html">P4::MergeData</a>
- object is passed to the block. This object contains the
- context of the merge.
- </p>
- <p><b>
- Note that this interface is evolving and is subject to
- change in future versions of P4Ruby.
- </b></p>
- <p>
- The block decides the outcome of the merge by evaluating to one
- of the following strings
- </p>
- <ul>
- <li>"ay" - Accept Yours</li>
- <li>"at" - Accept Theirs</li>
- <li>"am" - Accept Merge result</li>
- <li>"ae" - Accept Edited result</li>
- <li>"s" - Skip this merge</li>
- <li>"q" - Abort the merge</li>
- </ul>
- <pre>
- p4.run_resolve() do
- |md|
- puts( "Merging..." )
- puts( "Yours: #{md.your_name}" )
- puts( "Theirs: #{md.their_name}" )
- puts( "Base: #{md.base_name}" )
- puts( "Yours file: #{md.your_path}" )
- puts( "Theirs file: #{md.their_path}" )
- puts( "Base file: #{md.base_path}" )
- puts( "Result file: #{md.result_path}" )
- puts( "Merge Hint: #{md.merge_hint}" )
- result = md.merge_hint
- if( result == "e" && ENV.has_key?( "P4MERGE" ) )
- puts( "Invoking external merge application" )
- result = "s" # If the merge doesn't work, we'll skip
- result = "am" if md.run_merge()
- end
- result
- end
- </pre>
- </div>
- <a name="save_">
- <div class="method">
- <div class="methodheader">
- <table>
- <tr>
- <td class="meth_name">save_<spec type></td>
- <td class="proto">
- <i>p4</i>.save_<spec type>( [options], <i>hashOrString</i> ) -> <i>anArray</i>
- </td>
- </tr>
- </table>
- </div>
- The save_* methods are simply shortcut methods that allow you to quickly
- update the definitions of clients, labels, branches, etc. They're
- equivalent to
- <span class="inlinecode">
- p4.run( <spec type>, '-i', [options,] <i>hashOrString</i> ).shift
- </span>
- <pre>
- p4 = P4.new
- begin
- p4.connect
- client = p4.fetch_client()
- client[ "Owner" ] = p4.user?
- p4.save_client( client )
- rescue P4Exception
- p4.errors.each { |e| puts( e ) }
- ensure
- p4.disconnect
- end
- </pre>
- </div>
- <a name="tagged">
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">tagged</td>
- <td class="proto">
- <i>p4</i>.tagged -> true
- </td>
- </tr>
- </table>
- </div>
- Enables tagged output. Responses to Perforce commands which support
- tagged output will be converted into Ruby hashes. Must be called
- before connecting to the server.
- <pre>
- p4 = P4.new
- p4.tagged
- p4.connect
- ...
- p4.disconnect
- </pre>
- </div>
- <a name="user-eq">
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">user=</td>
- <td class="proto">
- <i>p4</i>.user = <i>aString</i> -> true
- </td>
- </tr>
- </table>
- </div>
- Set your Perforce username. If not set defaults to the value of P4USER
- taken from any P4CONFIG file in effect, then the value of P4USER in your
- environment and lastly your operating system user name.
- <pre>
- p4 = P4.new
- p4.user = "tony"
- p4.connect
- ...
- p4.disconnect
- </pre>
- </div>
- <a name="user-q">
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">user?</td>
- <td class="proto">
- <i>p4</i>.user? -> <i>aString</i>
- </td>
- </tr>
- </table>
- </div>
- Returns your current Perforce user name
- <pre>
- p4 = P4.new
- puts( p4.user? )
- </pre>
- </div>
- <a name="warnings">
- <div class="method">
- <div class="methodheader">
- <table width="100%">
- <tr>
- <td class="meth_name">warnings</td>
- <td class="proto">
- <i>p4</i>.warnings -> <i>anArray</i>
- </td>
- </tr>
- </table>
- </div>
- Returns the array of warnings which arose during execution of the last
- command.
- <pre>
- p4 = P4.new
- begin
- p4.connect
- p4.exception_level( P4::RAISE_ALL ) # "File(s) up-to-date" is a warning
- files = p4.run_sync
- rescue P4Exception => ex
- p4.warnings.each { |w| puts( w ) }
- ensure
- p4.disconnect
- end
- </pre>
- </div>
- </div>
- <h3>See Also</h3>
- <div class="seealso">
- <a href="P4DepotFile.html">P4DepotFile</a>
- <a href="P4Exception.html">P4Exception</a>
- <a href="P4Integration.html">P4Integration</a>
- <a href="P4Revision.html">P4Revision</a>
- <a href="P4MergeData.html">P4::MergeData</a>
- <a href="P4Spec.html">P4::Spec</a>
- </div>
- </body>
- </html>
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#21 | 5791 | Tony Smith | Add experimental support for passing a block to P4#run_resolve. The block is passed a P...4::MergeData object encapsulating the context of each merge performed. The block should evaluate to a string indicating the desired result of the merge: 'ay', 'at', 'am', 's', etc. The P4::MergeData object contains information about the files involved in the merge and can invoke an external merge tool. This is still experimental at this stage so the interface may change as it evolves. « |
18 years ago | |
#20 | 5311 | Tony Smith | Add new P4#api= method to allow users to lock scripts to a particular API level. This hel...ps when upgrading to new servers that extend support for tagged output to hitherto unsupported commands (2005.2 did a lot of that). See the C/C++ API Release Notes for the full details, but by way of example, to lock scripts to the 2005.1 interface use: p4.api = 57 « |
19 years ago | |
#19 | 5222 | Tony Smith | Improve debug output in P4Ruby: p4.debug = 1 * Show commands... being executed p4.debug = 2 * Show function calls p4.debug = 3 * Show data p4.debug = 4 * Show ruby garbage collection calls. Debug levels are cumulative as you'd expect. « |
19 years ago | |
#18 | 5169 | Tony Smith | Add missing parse_forms() call to example | 19 years ago | |
#17 | 4942 | Tony Smith | Add support for Unicode servers to P4Ruby. This change adds two new interfaces, P4#chars...et= and P4#charset? to set and get the charset respectively. « |
20 years ago | |
#16 | 4830 | Tony Smith | Add named constants for P4Ruby's exception levels. The valid levels are: ... P4::RAISE_NONE -- No exceptions P4::RAISE_ERRORS -- Exceptions on errors only P4::RAISE_ALL -- Exceptions on errors and warnings Also added P4#at_exception_level( level ) { ... } method to allow you to run a block of code at a different exception level and revert to the previous level when the block completes. Thanks to Johan Nilsson. Some doc tidying along with the docs for the features above. « |
20 years ago | |
#15 | 4810 | Tony Smith |
Fix the anchor names in the docs. Correction to previous change. |
20 years ago | |
#14 | 4809 | Tony Smith | Add P4#maxresults= and P4#maxscanrows= methods to allow you to place explicit limits on t...he execution of individual commands. These limits remain in force for all subsequent commands until they are removed by setting them to zero. Port of new functionality from P4Perl. « |
20 years ago | |
#13 | 4753 | Tony Smith | Add support for executing commands which prompt the user for input more than once during... their execution. A perfect example is 'p4 password' which prompts the user three times. This works by allowing P4#input() to take an array argument. Each time Perforce prompts the user (by calling ClientUserRuby::Prompt()), the array is shifted by one and the first value in the array is passed to Perforce. Thus, to change your password a three-element array is needed comprising of your old password, and the new password twice. To make this a little easier on the eye, this change also includes a thin wrapper called P4#run_password() which takes simply the old password and the new password and constructs a suitable input array. This change also includes docs for the above, and docs for P4#run_filelog() which were found to be missing. « |
20 years ago | |
#12 | 4680 | Tony Smith | Make P4Ruby return new P4::Spec objects instead of plain old hashes when parse_forms mode... is in use. A P4::Spec object is derived from Hash so should be backwards compatible with previous code. P4::Spec provides limited fieldname validation on forms and accessor methods for quick and easy access to the fields in the form. The accessor methods are all prefixed with '_' to avoid colliding with methods from the Hash parent class. This is a little ugly, but deriving from hash is a big win, so it's worth it. This change also fixes a minor bug found along the way. Spec parsing and formatting wouldn't work with labels, branches, depots and groups unless you'd previously run a P4::fetch_label( <label> ), P4::fetch_branch( <branch> ) etc. etc. This is because the spec parsing code internally runs one of these commands in order to grab the specdef from the server but it wasn't providing a spec name. i.e. it was using 'p4 client -o' and assuming that this would work for other types of spec too. It does, but not for all spec types. So, now the spec parsing code will use a bogus name for the spec types that require it. « |
20 years ago | |
#11 | 4653 | Tony Smith | More documentation tweaks. Just makes the pages look more like the reference pages in the... 'Pickaxe book' « |
20 years ago | |
#10 | 4652 | Tony Smith | Doc update for P4Ruby. Rework the html and the CSS to make the docs a little easier on t...he eye and easier to use too. « |
20 years ago | |
#9 | 4651 | Tony Smith | Add format_spec() method and format_* shortcuts to make it easy to convert a spec in a ha...sh back to its string form without sending it to the server. « |
20 years ago | |
#8 | 4593 | Tony Smith | Add support for 'p4 login' to P4Ruby per request from Robert Cowham. New installer to fol...low. « |
20 years ago | |
#7 | 4589 | Tony Smith | Update P4Ruby to support the new SetProg() method in the 2004.2 API. Whilst the new 'P4#p...rog=' method is always available, it's only functional if P4Ruby is built with a 2004.2 or later API. The build system got a bit of tidying up to support this change and the API version is now detected automatically if possible. I've also removed the --apilibdir and --apiincludedir flags as they complicate matters and I never use them and I don't believe anyone else does either. There are also some minor doc formatting tweaks to go along with the added documentation for prog=. « |
20 years ago | |
#6 | 4261 | Tony Smith | Add support for parsing arbitrary specs from strings in Ruby space. Useful with spec depo...ts. You might obtain the spec by running a "p4 print -q" against a file in a spec depot, but want to parse it into a Ruby hash. i.e. p4 = P4.new p4.parse_forms # Required! p4.connect buf = p4.run_print( "-q", "//specs/client/myclient" ) spec = p4.parse_client( buf ) # Or equivalently spec = p4.parse_spec( "client", buf ) « |
21 years ago | |
#5 | 4255 | Tony Smith | P4Ruby doc reformatting. Now uses CSS instead of 1x1 image and too many tables. Could no... doubt be improved upon, but it's a start. « |
21 years ago | |
#4 | 2426 | Tony Smith | Doc beautifying for P4Ruby. | 22 years ago | |
#3 | 2085 | Tony Smith | Get rid of specdef hack in the Ruby API. No need to store it in the hash, just grab it... from the RPC buffer when needed. « |
23 years ago | |
#2 | 1426 | Tony Smith | Cleaned up the debug output a little. Introduced some debug levels so you can decide (ro...ughly) what output you want to see. Level 1 shows command execution, connect and disconnect. Level 2 includes Level 1 and also shows the RPC callbacks as they happen. Level 3 includes 1 and 2 and also shows when Ruby garbage collection takes place. Converted all the simple methods of the form P4#meth( arg ) to aliases for P4#meth=. Added P4#debug= to complete the scheme. The P4#meth( arg ) forms are now deprecated. i.e. you should use: p4.user = "tony" and not: p4.user( "tony" ) It's just more Ruby-like. « |
23 years ago | |
#1 | 1324 | Tony Smith | P4/Ruby documentation update. Changed doc layout and added in docs for newly added method...s and classes. « |
23 years ago | |
//guest/tony_smith/perforce/API/Ruby/main/P4.html | |||||
#3 | 1166 | Tony Smith | Followup to previous change. Simplify the interface to getting results/errors and warnin...gs. No need for the P4Result class anymore so that's gone (though it's still there as a C++ class because it's useful) and so is P4#result. Now you get your errors/warnings and results using P4#errors, P4#warnings and P4#output all of which return arrays. « |
23 years ago | |
#2 | 1165 | Tony Smith | Minor reshuffle. Added the ability to disable exceptions completely if you don't like th...em or to have them raised only for errors (and not for warnings). Removed P4#warnings interface and replaced it with P4#exception_level. Some minor doc tweaks to go with the above change « |
23 years ago | |
#1 | 1164 | Tony Smith | Reworked exception handling (hopefully for the last time) in P4/Ruby. Now exceptions are... raised on completion of Perforce commands if any errors or warnings were received as part of executing the command. This change also adds documentation, and indexes the Ruby interface off my main page. Bad form to combine so many changes in one changelist, but it's getting late and I want to get them submitted! « |
23 years ago |