Class P4
Main interface to the
Helix Core Server
client API. Each P4
object provides you with a
thread-safe API level interface to
Helix Core Server. The
basic model is to:
- Instantiate your
P4
object. -
Specify your Helix Core Server client environment.
client
host
password
port
user
-
Set any options to control output or error handling:
exception_level
-
Connect to the Perforce service.
The Helix Core Server protocol is not designed to support multiple concurrent queries over the same connection. Multithreaded applications that use the C++ API or derived APIs (including P4Ruby) should ensure that a separate connection is used for each thread, or that only one thread may use a shared connection at a time.
- Run your Helix Core Server commands.
- Disconnect from the Perforce service.
Class Methods
P4.identify -> aString
Return the version of P4Ruby that you are using. Also reports the version of the OpenSSL library used for building the underlying Helix C/C++ API with which P4Ruby was built.
ruby -rP4 -e 'puts( P4.identify )'
Some of this information is already made available through the
predefined constants P4::VERSION
, P4::OS
, and
P4::PATCHLEVEL
.
P4.new -> aP4
Constructs a new P4 object.
p4 = P4.new()
Instance Methods
p4.api_level= anInteger -> anInteger
Sets the API compatibility level desired. This is useful when writing
scripts using
Helix Core Server
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
Helix Core Server
release and facilitate seamless upgrades. This method must be
called prior to calling P4#connect()
.
p4 = P4.new
p4.api_level = 67 # Lock to 2010.1 format
p4.connect
...
For more information about the API integer levels, see Protocol levels: server/client in the Helix Core Server Administrator Guide.
p4.api_level -> anInteger
Returns the current Helix C/C++ API compatibility level. Each iteration of the Helix Core Server is given a level number. As part of the initial communication, the client protocol level is passed between client application and the Helix Core Server. This value, defined in the Helix C/C++ API, determines the communication protocol level that the Helix Core Server client will understand. All subsequent responses from the Helix Core Server can be tailored to meet the requirements of that client protocol level.
For more information, see:
http://kb.perforce.com/article/512
p4.at_exception_level( lev ) { … } -> self
Executes the associated block under a specific exception level. Returns to the previous exception level when the block returns.
p4 = P4.new
p4.client = "www"
p4.connect
p4.at_exception_level( P4::RAISE_ERRORS ) do
p4.run_sync
end
p4.disconnect
p4.charset= aString -> aString
Sets the character set to use when connect to a Unicode enabled server.
Do not use when working with non-Unicode-enabled servers. By default, the
character set is the value of the P4CHARSET
environment
variable. If the character set is invalid, this method raises a
P4Exception
.
p4 = P4.new
p4.client = "www"
p4.charset = "iso8859-1"
p4.connect
p4.run_sync
p4.disconnect
p4.charset -> aString
Get the name of the character set in use when working with Unicode-enabled servers.
p4 = P4.new
p4.charset = "utf8"
puts( p4.charset )
p4.client= aString -> aString
Set the name of the client workspace 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
Helix Core Server
convention. Must be called before connecting to the Helix Core Server.
p4 = P4.new
p4.client = "www"
p4.connect
p4.run_sync
p4.disconnect
p4.client -> aString
Get the name of the Helix Core Server client currently in use.
p4 = P4.new
puts( p4.client )
p4.connect -> aBool
Connect to the
Helix Core Server. You must
connect before you can execute commands. Raises a
P4Exception
if the connection attempt fails.
p4 = P4.new
p4.connect
p4.connected? -> aBool
Test whether or not the session has been connected, and if the connection has not been dropped.
p4 = P4.newp4.connected?
p4.cwd= aString -> aString
Sets the current working directly. Can be called prior to executing any
Helix Core Server
command. Sometimes necessary if your script executes a
chdir()
as part of its processing.
p4 = P4.new
p4.cwd = "/home/bruno"
p4.cwd -> aString
Get the current working directory.
p4 = P4.new
puts( p4.cwd )
p4.delete_<spectype>( [options], name ) -> anArray
The delete methods are simply shortcut methods that allow you to quickly delete the definitions of clients, labels, branches, etc. These methods are equivalent to:
p4.run( "<spectype>", '-d', [options], "spec name" )
For example:
require "P4"
require "parsedate"
include ParseDate
now = Time.now
p4 = P4.new
begin
p4.connect
p4.run_clients.each do
|client|
atime = parsedate( client[ "Access" ] )
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
p4.disconnect -> true
Disconnect from the Helix Core Server.
p4 = P4.new
p4.connect
p4.disconnect
p4.each_<spectype<( arguments ) -> anArray
The each_<spectype>
methods are shortcut
methods that allow you to quickly iterate through clients, labels,
branches, etc. Valid <spectype>s are clients
,
labels
, branches
, changes
,
streams
, jobs
, users
,
groups
, depots
and servers
. Valid
arguments are any arguments that would be valid for the corresponding
run_<spectype>
command.
For example, to iterate through clients:
p4.each_clients do
|c|
# work with the retrieved client spec
end
is equivalent to:
clients = p4.run_clients
clients.each do
|c|
client = p4.fetch_client( c['client'] )
# work with the retrieved client spec
end
p4.env -> string
Get the value of a
Helix Core Server
environment variable, taking into account P4CONFIG
files and
(on Windows and macOS) the registry or user preferences.
p4 = P4.new
puts p4.env( "P4PORT" )
p4.errors -> anArray
Returns the array of errors which occurred during execution of the previous command.
p4 = P4.new
begin
p4.connect
p4.exception_level( P4::RAISE_ERRORS ) # ignore "File(s) up-to-date"
files = p4.run_sync
rescue P4Exception
p4.errors.each { |e| puts( e ) }
ensure
p4.disconnect
end
p4.exception_level= anInteger -> anInteger
Configures the events which give rise to exceptions. The following three levels are supported:
P4::RAISE_NONE
disables all exception raising and makes the interface completely procedural.P4::RAISE_ERRORS
causes exceptions to be raised only when errors are encountered.-
P4::RAISE_ALL
causes exceptions to be raised for both errors and warnings. This is the default.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
p4.exception_level -> aNumber
Returns the current exception level.
p4.fetch_<spectype>( [name] ) -> aP4::Spec
The fetch_<spectype>
methods are shortcut
methods that allow you to quickly fetch the definitions of clients,
labels, branches, etc. They’re equivalent to:
p4.run( "<spectype>", '-o', ... ).shift
For example:
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
p4.format_spec( "<spectype>", aHash )-> aString
Converts the fields in a hash containing the elements of a Helix Core Server form (spec) into the string representation familiar to users.
The first argument is the type of spec to format: for example,
client
, branch
, label
, and so on.
The second argument is the hash to parse.
There are shortcuts available for this method. You can use:
p4.format_<spectype>( hash )
instead of:
p4.format_spec( "<spectype>", hash )
where <spectype> is the name of a
Helix Core Server
spec, such as client
, label
, etc.
p4.format_<spectype> aHash -> aHash
The format_<spectype>
methods are shortcut
methods that allow you to quickly fetch the definitions of clients,
labels, branches, etc. They’re equivalent to:
p4.format_spec( "<spectype>", aHash )
p4.graph= -> aBool
Enable or disable support for graph depots. By default, support for depots of type graph is
enabled at 2017.1 or higher (P4#api_level()
>= 82).
Raises a P4Exception
if you attempt to enable graph depots on a pre-2017.1 server. You can enable or disable support for graph depots both before and after connecting to the server.
p4 = P4.new
p4.graph = false
p4.graph? -> aBool
Detects whether or not support for Helix Core Server graph depots is enabled.
p4 = P4.new
puts ( p4.graph? )
p4.graph = false
puts ( p4.graph? )
p4.handler= aHandler -> aHandler
Set the current output handler. This should be a subclass of
P4::OutputHandler
.
p4.handler -> aHandler
Get the current output handler.
p4.host= aString -> aString
Set the name of the current host. If not called, defaults to the value
of P4HOST
taken from any P4CONFIG
file present,
or from the environment as per the usual
Helix Core Server
convention. Must be called before connecting to the Helix Core Server.
p4 = P4.new
p4.host = "workstation123.perforce.com"
p4.connect
...
p4.disconnect
p4.host -> aString
Get the current hostname.
p4 = P4.new
puts( p4.host )
p4.input= ( aString|aHash|anArray ) -> aString|aHash|anArray
Store input for the next command.
Call this method prior to running a command requiring input from the
user. When the command requests input, the specified data will be
supplied to the command. Typically, commands of the form p4
cmd -i
are invoked using the
P4#save_<spectype>()
methods, which call
P4#input()
internally; there is no need to call
P4#input()
when using the
P4#save_<spectype>()
shortcuts.
You may pass a string, a hash, or (for commands that take multiple inputs from the user) an array of strings or hashes. If you pass an array, note that the array will be shifted each time Helix Core Server asks the user for input.
p4 = P4.new
p4.connect
change = p4.run_change( "-o" ).shift
change[ "Description" ] = "Autosubmitted changelist"
p4.input = change
p4.run_submit( "-i" )
p4.disconnect
p4.maxlocktime= anInteger -> anInteger
Limit the amount of time (in milliseconds) spent during data scans to
prevent the server from locking tables for too long. Commands that take
longer than the limit will be aborted. The limit remains in force until
you disable it by setting it to zero. See p4 help
maxlocktime
for information on the commands that support
this limit.
p4 = P4.new
begin
p4.connect
p4.maxlocktime = 10000 # 10 seconds
files = p4.run_sync
rescue P4Exception => ex
p4.errors.each { |e| $stderr.puts( e ) }
ensure
p4.disconnectend
p4.maxlocktime -> anInteger
Get the current maxlocktime
setting.
p4 = P4.new
puts( p4.maxlocktime )
p4.maxresults= anInteger -> anInteger
Limit the number of results
Helix Core Server
permits 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 p4 help
maxresults
for information on the commands that support
this limit.
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
p4.maxresults -> anInteger
Get the current maxresults
setting.
p4 = P4.new
puts( p4.maxresults )
p4.maxscanrows= anInteger -> anInteger
Limit the number of database records
Helix Core Server
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 p4 help
maxscanrows
for information on the commands that support
this limit.
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.disconnectend
p4.maxscanrows -> anInteger
Get the current maxscanrows
setting.
p4 = P4.new
puts( p4.maxscanrows )
p4.messages -> aP4::Message
Returns a message from the
Helix Core Server
in the form of a P4::Message
object.
p4 = P4.new
p4.exception_level = P4::RAISE_NONE
p4.run_sync
p4.run_sync # this second sync should return "File(s) up-to-date."
w = p4.messages[0]
puts ( w.to_s )
p4.p4config_file -> aString
Get the path to the current P4CONFIG
file.
p4 = P4.new
puts( p4.p4config_file )
p4.parse_<spectype>( aString ) -> aP4::Spec
This is equivalent to:
p4.parse_spec( "<spectype>", aString )
p4.parse_spec( "<spectype>", aString ) -> aP4::Spec
Parses a Helix Core Server form (spec) in text form into a Ruby hash using the spec definition obtained from the server.
The first argument is the type of spec to parse: client
,
branch
, label
, and so on. The second argument
is the string buffer to parse.
Note that there are shortcuts available for this method. You can use:
p4.parse_<spectype>( buf )
instead of:
p4.parse_spec( "<spectype>", buf )
Where <spectype> is one of client
,
branch
, label
, and so on.
p4.password= aString -> aString
Set your
Helix Core Server
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
Helix Core Server
conventions. This password will also be used if you later call
p4.run_login
to login using the 2003.2 and later ticket
system.
p4 = P4.new
p4.password = "mypass"
p4.connect
p4.run_login
p4.password -> aString
Get the current password or ticket. This may be the password in plain
text, or if you’ve used P4#run_login()
, it’ll be the value
of the ticket you’ve been allocated by the server.
p4 = P4.new
puts( p4.password )
p4.port= aString -> aString
Set the host and port of the Helix Core 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.
p4 = P4.new
p4.port = "localhost:1666"
p4.connect
...
p4.disconnect
p4.port -> aString
Get the host and port of the current Helix Core Server.
p4 = P4.new
puts( p4.port )
p4.prog= aString -> aString
Set the name of the program, as reported to
Helix Core Server
system administrators running p4 monitor show -e
in
Helix Core Server
2004.2 or later releases.
p4 = P4.new
p4.prog = "sync-script"
p4.connect
...
p4.disconnect
p4.prog -> aString
Get the name of the program as reported to the Helix Core Server.
p4 = P4.new
p4.prog = "sync-script"
puts( p4.prog )
p4.progress= aProgress -> aProgress
Set the current progress indicator. This should be a subclass of
P4::Progress
.
p4.progress -> aProgress
Get the current progress indicator.
p4.run_<cmd>( arguments ) -> anArray
This is equivalent to:
p4.run( "cmd", arguments... )
p4.run( aCommand, arguments… ) -> anArray
Base interface to all the run methods in this API. Runs the specified
Helix Core Server
command with the arguments supplied. Arguments may be in any form as long
as they can be converted to strings by to_s
. However, each command's options should be passed as quoted and comma-separated strings, with no leading space. For example:
p4.run("print","-o","test-print","-q","//depot/Jam/MAIN/src/expand.c")
Failing to pass options in this way can result in confusing error messages.
The P4#run()
method returns an array of results whether the
command succeeds or fails; the array may, however, be empty. Whether the
elements of the array are strings or hashes depends on (a) server support
for tagged output for the command, and (b) whether tagged output was
disabled by calling p4.tagged = false
.
In the event of errors or warnings, and depending on the exception level
in force at the time, P4#run()
will raise a
P4Exception
. If the current exception level is below
the threshold for the error/warning, P4#run()
returns the
output as normal and the caller must explicitly review
P4#errors()
and P4#warnings()
to check for
errors or warnings.
p4 = P4.new
p4.connect
spec = p4.run( "client", "-o" ).shift
p4.disconnect
Shortcuts are available for P4#run()
. For example:
p4.run_command( args )
is equivalent to:
p4.run( "command", args )
There are also some shortcuts for common commands such as editing Helix Core Server forms and submitting. Consequently, this:
p4 = P4.new
p4.connect
clientspec = p4.run_client( "-o" ).shift
clientspec[ "Description" ] = "Build client"
p4.input = clientspec
p4.run_client( "-i" )
p4.disconnect
may be shortened to:
p4 = P4.new
p4.connect
clientspec = p4.fetch_client
clientspec[ "Description" ] = "Build client"
p4.save_client( clientspec )
p4.disconnect
The following are equivalent:
|
|
|
|
|
|
As the commands associated with
P4#fetch_<spectype>()
typically return only one
item, these methods do not return an array, but instead return the first
result element.
For convenience in submitting changelists, changes returned by
P4#fetch_change()
can be passed to
P4#run_submit
. For example:
p4 = P4.new
p4.connect
spec = p4.fetch_changespec[ "Description" ] = "Automated change"
p4.run_submit( spec )
p4.disconnect
p4.run_filelog( fileSpec ) -> anArray
Runs a p4 filelog
on the fileSpec
provided and returns an array of P4::DepotFile
results when executed in tagged mode, and an array of strings when
executed in non-tagged mode. By default, the raw output of p4
filelog
is tagged; this method restructures the output
into a more user-friendly (and object-oriented) form.
p4 = P4.new
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
p4.run_login( arg… ) -> anArray
Runs p4 login
using a password or ticket set by the
user.
p4.run_password( oldpass, newpass ) -> anArray
A thin wrapper to make it easy to change your password. This method is (literally) equivalent to the following code:
p4.input( [ oldpass, newpass, newpass ] )
p4.run( "password" )
For example:
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
p4.run_resolve( args ) [ block ] -> anArray
Interface to p4 resolve
. Without a block, simply
runs a non-interactive resolve (typically an automatic resolve).
p4.run_resolve( "-at" )
When a block is supplied, the block is invoked once for each merge
scheduled by
Helix Core Server. For
each merge, a P4::MergeData
object is passed to the
block. This object contains the context of the merge.
The block determines the outcome of the merge by evaluating to one of the following strings:
Block string | Meaning |
---|---|
|
Accept Yours. |
|
Accept Theirs. |
|
Accept Merge result. |
|
Accept Edited result. |
|
Skip this merge. |
|
Abort the merge. |
For example:
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" )
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
p4.run_submit( [aHash], [arg…] ) -> anArray
Submit a changelist to the server. To submit a changelist, set the fields of the changelist as required and supply any flags:.
change = p4.fetch_change
change._description = "Some description"
p4.run_submit( "-r", change )
You can also submit a changelist by supplying the arguments as you would on the command line:
p4.run_submit( "-d", "Some description", "somedir/..." )
p4.run_tickets( ) -> anArray
Get a list of tickets from the local tickets file. Each ticket is a hash
object with fields for Host
, User
, and
Ticket
.
p4.save_<spectype>( hashOrString, [options] ) -> anArray
The save_<spectype>
methods are shortcut
methods that allow you to quickly update the definitions of clients,
labels, branches, etc. They are equivalent to:
p4.input = hashOrStringp4.run( "<spectype>", "-i" )
For example:
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
p4.server_case_sensitive? -> aBool
Detects whether or not the server is case-sensitive.
p4.server_level -> anInteger
Returns the current Helix Core Server level. Each iteration of the Helix Core Server is given a level number. As part of the initial communication this value is passed between the client application and the Helix Core Server. This value is used to determine the communication that the Helix Core Server will understand. All subsequent requests can therefore be tailored to meet the requirements of this Server level.
For more information about the Helix Core Server version levels, see Protocol levels: server/client in the Helix Core Server Administrator Guide.
p4.server_unicode? -> aBool
Detects whether or not the server is in unicode mode.
p4.set_env= ( aString, aString ) -> aBool
On Windows or macOS, set a variable in the registry or user preferences. To unset a variable, pass an empty string as the second argument. On other platforms, an exception is raised.
p4 = P4.new
p4.set_env = ( "P4CLIENT", "my_workspace" )
p4.set_env = ( "P4CLIENT", "" )
p4.streams= -> aBool
Enable or disable support for streams. By default, streams support is
enabled at 2011.1 or higher (P4#api_level()
>= 70).
Raises a P4Exception
if you attempt to enable streams
on a pre-2011.1 server. You can enable or disable support for streams
both before and after connecting to the server.
p4 = P4.new
p4.streams = false
p4.streams? -> aBool
Detects whether or not support for Helix Core Server Streams is enabled.
p4 = P4.new
puts ( p4.streams? )
p4.streams = false
puts ( p4.streams? )
p4.tagged( aBool ) { block }
Temporarily toggles the use of tagged output for the duration of the block, and then resets it when the block terminates.
p4.tagged= aBool -> aBool
Sets tagged output. By default, tagged output is on.
p4 = P4.new
p4.tagged = false
p4.tagged? -> aBool
Detects whether or not you are in tagged mode.
p4 = P4.new
puts ( p4.tagged? )
p4.tagged = false
puts ( p4.tagged? )
p4.ticketfile= aString -> aString
Sets the location of the P4TICKETS
file.
p4 = P4.new
p4.ticketfile = "/home/bruno/tickets"
p4.ticketfile -> aString
Get the path to the current P4TICKETS
file.
p4 = P4.new
puts( p4.ticketfile )
p4.track= -> aBool
Instruct the server to return messages containing performance tracking information. By default, server tracking is disabled.
p4 = P4.new
p4.track = true
p4.track? -> aBool
Detects whether or not performance tracking is enabled.
p4 = P4.new
p4.track = true
puts ( p4.track? )
p4.track = false
puts ( p4.track? )
p4.track_output -> anArray
If performance tracking is enabled with p4.track=
, returns
a list of strings corresponding to the performance tracking output for
the most recently-executed command.
p4 = P4.new
p4.track = true
p4.run_info
puts ( p4.track_output[0].slice(0,3) ) # should be "rpc"
p4.user= aString -> aString
Set the
Helix Core Server
username. If not called, defaults to the value of P4USER
taken from any P4CONFIG
file present, or from the
environment as per the usual
Helix Core Server
convention. Must be called before connecting to the Helix Core Server.
p4 = P4.new
p4.user = "bruno"
p4.connect
...
p4.disconnect
p4.user -> aString
Returns the current Helix Core Server username.
p4 = P4.new
puts( p4.user )
p4.version= aString -> aString
Set the version of your script, as reported to the Helix Core Server.
p4.version -> aString
Get the version of your script, as reported to the Helix Core Server.
p4.warnings -> anArray
Returns the array of warnings that arose during execution of the last command.
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