P4.html #1

  • //
  • guest/
  • perforce_software/
  • p4ruby/
  • main/
  • doc/
  • P4.html
  • View
  • Commits
  • Open Download .zip Download (36 KB)
<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">&lt; 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 -&gt; <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 -&gt; <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_&lt;spec type&gt;</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_&lt;spec type&gt;</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_&lt;spec type&gt;</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 ) { ... } -&gt; <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> -&gt; <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> -&gt; <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? -&gt; <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> -&gt; 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? -&gt; <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 -&gt; <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> -&gt; 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? -&gt; <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>  -&gt; 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_&lt;spec type&gt;</td>
	    <td class="proto">
	      <i>p4</i>.delete_&lt;spec type&gt;( [options], name ) -&gt; <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( &lt;spec type&gt;, '-d', [options], &lt;spec name&gt; ).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 -&gt; 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 -&gt; <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> -&gt; <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? -&gt; <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_&lt;spec type&gt;</td>
	    <td class="proto">
	      <i>p4</i>.fetch_&lt;spec type&gt;( [name] ) -&gt; <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( &lt;spec type&gt;, '-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( &lt;spec type&gt;, aHash )-&gt; 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_&lt;spec type&gt;( hash )
      </pre>

      instead of 

      <pre>
    p4.format_spec( &lt;spec type&gt;, hash )
      </pre>

      Where &lt;spec type&gt; 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> -&gt; 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? -&gt; <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 ) -&gt; true or false<br>
	      <i>p4</i>.input( aHash ) -&gt; true or false<br>
	      <i>p4</i>.input( anArray ) -&gt; 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> -&gt; <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 =&gt; 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> -&gt; <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 =&gt; 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 -&gt; <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 =&gt; 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 -&gt; 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( &lt;spec type&gt;, aString )-&gt; 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_&lt;spec type&gt;( buf )
      </pre>

      instead of 

      <pre>
    p4.parse_spec( &lt;spec type&gt;, buf )
      </pre>

      Where &lt;spec type&gt; 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>  -&gt; 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? -&gt; <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> -&gt; 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> -&gt; 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? -&gt; <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> ) -&gt; <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>) -&gt; <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>) -&gt; <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> ] -&gt; <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" &amp;&amp; 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_&lt;spec type&gt;</td>
	    <td class="proto">
	      <i>p4</i>.save_&lt;spec type&gt;( [options], <i>hashOrString</i> ) -&gt; <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( &lt;spec type&gt;, '-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 -&gt; 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> -&gt; 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? -&gt; <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 -&gt; <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 =&gt; 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
#2 14520 tony Replace old P4Ruby documentation with a RELNOTES file, (and
ultimately, Doug's new manual), and update the MANIFEST to
match (and include the new tests)

I've also removed the old installer files as our new installer
won't use them.
#1 14480 tony Add P4Ruby 1.5944 to main as start-point for the first
productized release of P4Ruby