NAME
VCS::CMSynergy - Perl interface to Telelogic CM Synergy (aka Continuus/CM)
SYNOPSIS
use VCS::CMSynergy;
$ccm = VCS::CMSynergy->new(%attr);
($rc, $out, $err) = $ccm->ccm($ccm_command, @ccm_args);
($rc, $out, $err) = $ccm->any_ccm_command(@ccm_args);
$ary_ref = $ccm->query(@ccm_args);
$ary_ref = $ccm->query_arrayref($query, @keywords);
$ary_ref = $ccm->query_hashref($query, @keywords);
$ary_ref = $ccm->query_object($query);
$ary_ref = $ccm->finduse(@args);
$path = $ccm->findpath($file_spec, $proj_vers);
$ary_ref = $ccm->history(@ccm_args);
$ary_ref = $ccm->history_arrayref($file_spec, @keywords);
$ary_ref = $ccm->history_hashref($file_spec, @keywords);
$ary_ref = $ccm->ls(@ccm_args);
$ary_ref = $ccm->ls_object($file_spec);
$ary_ref = $ccm->ls_arrayref($file_spec, @keywords);
$ary_ref = $ccm->ls_hashref($file_spec, @keywords);
$value = $ccm->get_attribute($attr_name, $file_spec);
$ccm->set_attribute($attr_name, $file_spec, $value);
$hash_ref = $ccm->list_attributes($file_spec);
$delim = $ccm->delimiter;
$database = $ccm->database;
$ENV{CCM_ADDR} = $ccm->ccm_addr;
@types = $ccm->types;
$last_error = $ccm->error;
$last_ccm_command = $ccm->ccm_command;
($ccm, $schema, $informix, @patches) = $h->version;
@ary = $h->databases;
$ary_ref = $h->ps;
$ary_ref = $h->ps(\%attr);
$ary_ref = $h->status;
This synopsis only lists the major methods. Methods for administering users and their roles are described in the VCS::CMSynergy::Users documentation.
DESCRIPTION
use VCS::CMSynergy;
my $ccm = VCS::CMSynergy->new(database => "/ccmdb/test/tut62/db");
$ccm->checkout(qw(foo/bar.c@foo~user -to test))
or die "checkout failed: ".$ccm->error;
my $csrcs = $ccm->query_hashref("type = 'csrc'",
qw(displayname modify_time));
if ($csrcs)
{
print "$_->{displayname} $->{modify_time}\n" foreach (@$csrcs);
}
METHODS
new
my $ccm = VCS::CMSynergy->new( database => "/ccmdb/foo/db" )
or die VCS::CMSynergy->error;
Starts a new CM Synergy session. Returns a session handle if it succeeds.
If it fails to start a session, it returns undef
. Use VCS::CMSynergy->error
to get the error string printed by CM Synergy.
Multiple simultaneous sessions to multiple databases or with engines running on different hosts, even using different versions of CM Synergy, are supported.
new
issues a ccm start command and remembers the CCM_ADDR
in the session object (together with other session state). The session is stopped (ccm stop) when the session object is destroyed (see "DESTROY").
new
is called with an attribute hash. The following attributes are currently supported:
database
(string)-
CM Synergy database path.
This is the only attribute required on Unix systems.
host
(string)-
CM Synergy engine host to use.
It defaults to the local host.
role
(string)-
User's initial CM Synergy role.
It defaults to
developer
. user
(string)-
CM Synergy user.
This attribute is available and required on Windows systems only.
password
(string)-
User's password.
This attribute is required on Windows systems or when using ESD to connect to the CM Synergy engine.
ini_file
(string)-
CM Synergy ini file to use.
In contrast to the CM Synergy ccm start command there is no default ini file consulted. (On Unix systems this is achieved by executing ccm start with the option
-f /dev/null
.) The reason is that we want scripts to behave in a reproducible way. Otherwise the script might accidentally work with the current contents of the current user's ini file, but might fail when invoked by another user. Or it might fail when invoked by the same user at a later time because of changes to her ini file (e.g. because of another session between invocations of the script). So if you really want to rely on an ini file, you have to supply it explicitly. CCM_ADDR
(string)-
Specifies the RFC address of an established CM Synergy session.
If you specify this attribut "new" does not create a new session, but will attach to the one specified. Also, implicitly sets
KeepSession
to "on" so that destruction of the new session handle will not cause a ccm stop. However, settingKeepSession
explicitly will take precedence.Note that there is no default value. In particular, "new" ignores the environment variable of the same name.
CCM_HOME
(string)-
Value of the
CCM_HOME
environment variable to use for this session.It defaults from the environment variable of the same name, i.e.
$ENV{CCM_HOME}
.This is only of interest if you have multiple version of CM Synergy installed. You can have simultaneous sessions using different CM Synergy versions (the module takes care of setting the
CCM_HOME
variable appropriately before issuing anyccm
commands). ui_database_dir
(string)-
Specifies the path name to which your database information is copied when you are running a remote client session. This corresponds to the
-u pathname
option for ccm start.Note: This option is particularly useful for Windows clients. If "new" fails with something like
Server Database Path ... is not accessible from this Client. Please specify a Client Database Path
you should specify this option with a local directory path, e.g.
my $ccm = VCS::CMSynergy->new(..., ui_database_dir => 'c:\\temp', ...);
The value is what you would enter under "Client Information"/"Database Path" in the GUI's "Startup Info" window. Or you can set ui_database_dir in the [Options] section of the system ini file (note that setting it in your personal ini file won't do, as this file is not read by "new" by default).
remote_client
(boolean)-
If the value is "on", it specifies that you want to start the CM Synergy session as a remote client. This corresponds to the
-rc
option for ccm start. This option is only usefull on Unix systems. It defaults to "off". PrintError
(boolean)-
This attribute can be used to force errors to generate warnings (using carp) in addition to returning error codes in the normal way. When set to true, any method which results in an error occuring will cause the corresponding
$ccm->error
to be printed to stderr.It defaults to "on".
Note: "PrintError" and "RaiseError" below are stolen from the excellent DBI module.
RaiseError
(boolean)-
This attribute can be used to force errors to raise exceptions (using croak) rather than simply return error codes in the normal way. When set to true, any method which results in an error will cause effectively a
die
with the actual$ccm->error
as the message.It defaults to "off".
If you turn
RaiseError
on then you'd normally turnPrintError
off. IfPrintError
is also on, then thePrintError
is done first (naturally).Typically
RaiseError
is used in conjunction witheval { ... }
to catch the exception that's been thrown and followed by anif ($@) { ... }
block to handle the caught exception.If you want to temporarily turn
RaiseError
off (inside a library function that is likely to fail, for example), the recommended way is like this:{ local $ccm->{RaiseError}; # localize and turn off for this block ... }
The original value will automatically and reliably be restored by Perl, regardless of how the block is exited. The same logic applies to other attributes, including
PrintError
. HandleError
(code ref)-
This attribute can be used to provide your own alternative behaviour in case of errors. If set to a reference to a subroutine then that subroutine is called when an error is detected (at the same point that "RaiseError" and "PrintError" are handled).
The subroutine is called with three parameters: the error message string that "RaiseError" and "PrintError" would use, the
VCS::CMSynergy
object being used, and the value being returned by the method that failed (typically undef).If the subroutine returns a false value then the "RaiseError" and/or "PrintError" attributes are checked and acted upon as normal. Otherwise the error is considered "handled" and execution proceeds normally with a return from the method.
For example, to "die" with a full stack trace for any error:
use Carp; $ccm->{HandleError} = sub { confess(shift) };
KeepSession
(boolean)-
If this attribute is "on" then destruction of the new session handle will not cause a ccm stop.
This may be used if you want to create a new CM Synergy session in one program and then re-use it in another program (since session creation is a rather time consuming operation). In this case you should use
/ccm_addr
to extract the session's RFC address (after/new
returns) and somehow pass it on to the other program.It defaults to "off" unless you also specify
CCM_ADDR
. UseCoprocess
(boolean)-
This feature is highly experimental, use it at your own risk.
You must have the Expect module installed to use this feature. (Since Expect is not available for Win32 systems,
UseCoprocess
is ignored there.)If
UseCoprocess
is "off",VCS::CMSynergy.pm
executes a separateccm
process whenever it invokes the CM Synergy CLI, e.g.$ccm->checkout('foo.c'); $ccm->set_attribute('color', 'foo.c', 'blue'); $csources = $ccm->query("name match '*.c'");
results in the execution of the following three processes:
ccm checkout foo.c ccm attribute -modify color -value blue foo.c ccm query "name match '*.c'"
In particular, we incur the startup overhead of ccm three times. This overhead is noticable, esp. if you are doing lots of CM Synergy operations.
If
UseCoprocess
is "on", only one ccm process per CM Synergy session ever gets executed. The way it works is thatVCS::CMSynergy->new
starts an "interactive" (i.e. one invoked without arguments) ccm process in the background. Later invocations of the CM Synergy CLI pipe their commands to its input and read back the output (up to the next"ccm>"
prompt). The actual command is then followed in the same way byset error
to retrieve the success status. Destruction of the session object will cause termination of this "coprocess" (via "stop" or "exit" depending on the setting of "KeepSession").The "coprocess" method avoids the startup overhead, but may run into other problems:
The "interactive" ccm imposes stricter limits on the length of one CLI command (experimentally put at ~2000 bytes) than the "batch" ccm (where the limit on the arguments of a process is typically imposed by the operating system). Moreover, it will silently truncate the command and not signal an error (unless the truncation causes a syntax error).
The current method to communicate with the "coprocess" does not allow for separation of its stdout and stderr.
FIXME: document
chdir
problemUseCoprocess
does not work under Win32 at all.
The default value of
UseCoprocess
is "off".
DESTROY
$ccm->DESTROY;
Stops the CM Synergy session represented by the session handle by executing ccm stop (unless the session has the KeepSession
attribut set).
You should never call this method explicitly, as it is invoked by the Perl runtime when the Perl process exits (either by calling exit
or because of a die
). Hence, a script using the VCS::CMSynergy
module will not leave any CM Synergy sessions hanging around.
Actually, the Perl runtime will call DESTROY
when the last reference to a session handle goes out of scope, so in the following example each session will be stopped as soon as one loop through the foreach
body is completed, i.e. there is at most one session in progress at any one time:
my @databases = ...; # a list of CM Synergy databases
foreach my $db (@databases)
{
my $ccm = VCS::CMSynergy->new( database => $db, ... );
...
# perform some operation on $db
...
# session is stopped as "my" variable $ccm is about to go out of scope
}
Note: The correct way to explicitly stop a session is neither
$ccm->stop;
nor is it
$ccm->DESTROY;
Though both forms will execute ccm stop, the first form makes $ccm
a VCS::CMSynergy
object with an invalid RFC address (i.e. attribute CCM_ADDR), while the second form leaves you with an "empty" VCS::CMSynergy
object. Instead, you should rather say
$ccm = undef;
ccm
($rc, $out, $err) = $ccm->ccm($command, @args);
This is the workhorse of the VCS::CMSynergy module. It executes ccm with command $command
and (optional) parameters @args
. In array context it returns a three-element array consisting of the (operating system) exit code of ccm, and what ccm printed on stdout and stderr. Note that the exit code is 0 if ccm operated successfully. On DOSish operating systems the (possibly multi-line) strings $out
and $err
have been read by Perl in "text" mode, i.e. contain LF characters instead of CRLF. In any case, $out
and $err
have been chomp
ed.
In scalar context ccm
returns the "logical" exit code, i.e. !$rc
, so that you can write:
$ccm->ccm('checkout', $file_spec)
or die "checkout failed: ".$ccm->error;
Note that you must pass every ccm
argument or option as a single Perl argument. For literal arguments the qw()
notation may come in handy, e.g.
($rc, $out, $err) = $ccm->ccm(qw(finduse -state working));
Most specialized methods in the VCS::CMSynergy module are ultimately implemented via the "ccm" method. Using it directly is only recommended for commands that perform some action, e.g. ccm checkout, as opposed to query-like commands. For the latter, e.g. ccm query, use one of the methods that return the information in structured form, e.g. "query_arrayref and query_hashref", instead of having to parse $out
yourself.
In fact, there is a shortcut for "action" commands: if you call a non-existent method on a VCS::CMSynergy object, it tries to invoke the "ccm" method with the original method name as the $command
followed by the parameters of the original call, i.e.
$ccm->checkout($file_spec);
and
$ccm->ccm('checkout', $file_spec);
are equivalent (given that there is no real checkout
method). Return values are those of "ccm" (depending on context). This is accomplished by a suitable AUTOLOAD
method.
ccm_addr
print "CCM_ADDR=", $ccm->ccm_addr;
Returns the session's RFC address.
ccm_command
$last_session_command = $ccm->ccm_command;
Returns the last CM Synergy command invoked in the session.
ccm_home
print "CCM_HOME=", $ccm->ccm_home;
Returns the session's CCM_HOME.
out
Returns the raw standard output of the last CM Synergy command invoked in the session. In scalar context the output is returned as a possibly multi-line string. In list context it is returned as an array of pre-chomped lines.
err
Returns the raw standard error of the last CM Synergy command invoked in the session. The return value is a possibly multi-line string regardless of calling context.
database
$database = $ccm->database;
Returns the database path in canonical form (i.e. with a trailing "/db"
):
delimiter
$delim = $ccm->delimiter;
Returns the database delimiter.
error
$last_session_error = $ccm->error;
Returns the last error that occured in the session.
query
$ary_ref = $ccm->query(@args);
Executes the ccm query command with the given @args
as parameters. The output (as formatted by the -format
option) is split into lines. These are chomped and a reference to the resulting array of strings is returned.
If there a no hits, a reference to an empty array is returned. (Note that ccm query considers this an error, but the VCS::CMSynergy module does not.)
If there was an error, undef
is returned.
Note that you must pass every ccm query argument or option as a single Perl argument. For literal arguments the qw()
notation may come in handy. Example:
$result = $ccm->query(qw(-t csrc -f), '%displayname %modify_time');
print "$_\n" foreach (@$result);
If you are interested in the value of several attributes for the result set of the query, you should look at the "query_arrayref and query_hashref" methods that return this information in structured form. If you are only interested in the identity of objects in the result set, you should look at the "query_object" method.
Note that "query" will probably produce unpredictable results when the -format
option references attributes that can have multi-line values, e.g. status_log
. "query_arrayref and query_hashref" handle this case correctly.
query_arrayref and query_hashref
$ary_ref = $ccm->query_arrayref($query, @keywords);
print "@$_\n" foreach @$ary_ref;
$ary_ref = $ccm->query_hashref($query, @keywords);
print "@$_{@keywords}\n" foreach @$ary_ref;
query_arrayref
and query_hashref
execute ccm query with the query expression $query
asking for the values of the built-in keywords or attributes supplied in @keywords
. They both return a reference to an array of references, one per result row.
query_arrayref
represents a row as an array containing the values of the keywords for that particular object in the result set (in the order given by @keywords
).
query_hashref
represents a row as a hash containing attribute and value pairs where the keys are the @keywords
.
If the query returned no hits, both query_arrayref
and query_hashref
return a reference to an empty array.
If there was an error, undef
is returned.
If the value of a keyword or an attribute is undefined or the attribute is not present, the actual value of the corresponding array or hash element is undef
(whereas ccm query would print it as the string "void
").
The following names may also be used as keywords though they are neither built-in nor attributes:
object
-
The value is a
VCS::CMSynergy::Object
representing the object in the result set. finduse
-
The value is a reference to a hash identifying in what parts of what projects the object is used. A key in the hash is the project's objectname. The hash value is the corresponding relative path (including the object's name) in the project. This information is the same as reported by ccm finduse. In fact, if this keyword is given, "query_arrayref and query_hashref" invoke ccm finduse -query $query rather than ccm query $query. Example:
my $result = $ccm->query_arrayref( "name = 'main.c'", qw(objectname finduse));
returns (as formatted by Data::Dumper):
$result = [ [ 'main.c-1:csrc:3', # objectname { # finduse 'guilib-1.0' => 'guilib/sources/main.c', 'guilib-int' => 'guilib/sources/main.c', 'guilib-darcy' => 'guilib/sources/main.c' } ], ... ];
objectname
-
objectname
is indeed a built-in keyword. However, CM Synergy ccm query -f %objectname actually returns the deprecated fullname (i.e.subsystem/cvtype/name/version
) for certain model objects (e.g. try ccm query -f %objectname -i base), but refuses to accept them as command arguments. ThereforeVCS::CMSynergy
will rewrite these fullnames to correct objectnames before returning them from <query_arrayref> orquery_hashref
.
Note: The keyword or attribute names given in @keywords
should not contain a leading %
. Example:
my $result = $ccm->query_hashref("name match '*.c'",
qw(displayname type modify_time);
foreach my $row (@$result)
{
print "$row->{displayname} last modified at $row->{modify_time}\n";
...
}
Note: This query method does not support any of the shortcut query options of the ccm query command, e.g. -o owner or -n name. However, a different shortcut syntax is supported, see "shortcut query notation".
query_object
$ary_ref = $ccm->query_object($query);
Executes ccm query with the query expression $query
and returns a reference to an array of VCS::CMSynergy::Object
s that satisfy the query.
If there a no hits, a reference to an empty array is returned.
If there was an error, undef
is returned.
Note: This is a convenience method. It might be implemented using query_arrayref
:
sub query_object
{
my ($self, $query) = @_;
my $ary = $self->query_arrayref($query, 'object') or return undef;
[ map { $_->[0] } @$ary ];
}
shortcut query notation
query_arrayref
, query_hashref
and query_object
support a shortcut notation for their common $query
parameter. To use this shortcut, supply a hash reference for $query
(instead of a simple string):
$result = $ccm->query_hashref(
{ type => 'csrc', match => '*.cpp' }, qw(objectname status));
Every key => value
represents a simple query. Simple queries are combined with AND. The following simple queries are accepted:
- "key" => $scalar
-
This is translated to CMSynergy query syntax as
key = '$scalar'
. Note the quotes around$scalar
. However, quotes are omitted if$scalar
is either the string"TRUE"
or"FALSE"
. In general,key
is the name of an attribute. The following keys are treated specially:- match
-
match => $scalar
is short forname match '$scalar'
. - task
-
task => $tasknr
is short foris_associated_cv_of(cvtype = 'task' and task_number = '$tasknr')
. This corresponds to CM Synergy's ccm query -task tasknr.
- "key" => \@array
-
This is translated as a call of a query function, i.e.
key('$array[0]', ...)
. Quoting is as described above. Example:$ccm->query_object( { hierarchy_project_members => [ 'toolkit-1.0:project:1', 'none' ] });
- "key" => \%hash
-
This is translated as a call of a query function with a nested query as parameter: Example:
$rel = '6.0'; $ccm->query_object( { is_member_of => { release => $rel, match => '*web*' });
gets translated to
"is_member_of(release='6.0' and name match '*web*')"
history
$ary_ref = $ccm->history(@args);
Executes the ccm history command with the given @args
as parameters. The output (probably formatted by the -format
option) is split into chunks at the divider line (a line consisting of lots of asterisks). A reference to the resulting array of (multi-line) strings is returned.
If there was an error, undef
is returned.
Note that you must pass every ccm history argument or option as a single Perl argument. For literal arguments the qw()
notation may come in handy.
If you are interested in the successor or predecessor or certain attributes of an object in the history, you should look at the "history_arrayref and history_hashref" methods that return this information in structured form.
history_arrayref and history_hashref
$ary_ref = $ccm->history_arrayref($file_spec, @keywords);
$ary_ref = $ccm->history_hashref($file_spec, @keywords);
history_arrayref
and history_hashref
execute ccm history for $file_spec
asking for the values of the built-in keywords or attributes supplied in @keywords
. The both return a reference to an array of references, one per history entry.
history_arrayref
represents a history entry as an array containing the values of the keywords for that particular object in the history (in the order given by @keywords
).
history_hashref
represents a history entry as a hash containing attribute and value pairs where the keys are the @keywords
.
If there was an error, undef
is returned.
If the value of a keyword or an attribute is undefined or the attribute is not present, the actual value of the corresponding array or hash element is undef
(whereas ccm history would print it as the string "void
").
The following names may also be used as keywords though they are neither built-in nor attributes:
object
-
The value is a
VCS::CMSynergy::Object
representing the object in the history. predecessors
-
The value returned is a reference to an array of
VCS::CMSynergy::Object
s that represent the given object's predecessors. successors
-
The value returned is a reference to an array of
VCS::CMSynergy::Object
s that represent the given object's successors.
Note the following differences from ccm history:
Only one
$file_spec
is allowed.There is no
-p
(project) option. If you want to get the history of a project use the full objectname of the project for$file_spec
.The keyword or attribute names given in
@keywords
should not contain a leading%
. Example:my $result = $ccm->history_hashref( 'math.h-1:incl:1', qw(displayname modify_time successors)); foreach my $row (@$result) { print "$row->{displayname}: last modified at $row->{modify_time}\n"; print "\t$_\n" foreach (@{ $row->{successors} }); ... }
finduse
$ary_ref = $ccm->finduse(@args);
Executes the ccm finduse command with the given @args
as parameters. It returns a reference to an array of rows, usually one per file_spec
given in @args
, or one per query result if -query $query_expression
is present in @args
.
Each row is a reference to an array of two elements. The first element is the description of the object. The second element is a reference to a hash identifying in what parts of what projects the object is used. A key in the hash denotes the project in the form "project_name-project_version". The hash value is the corresponding relative path (including the object's name) in the project. If there are no uses of the object in the given scope the hash is empty. This usage information is in the same form as that for the pseudo keyword "finduse"
of the "query_arrayref and query_hashref" methods.
If there was an error, undef
is returned.
Note that you must pass every ccm finduse argument or option as a single Perl argument. For literal arguments the qw()
notation may come in handy.
If you are interested in usage information for all objects matching a query you should look at the "query_arrayref and query_hashref" methods, esp. the "finduse"
keyword.
Example (recreate the output of the ccm finduse command):
foreach (@{ $ccm->finduse(@args) })
{
my ($desc, $uses) = @$_;
print "$desc\n";
if (keys %$uses)
{
while (my ($proj_vers, $path) = each %$uses)
{
print "\t$path\@$proj_vers\n"
}
}
else
{
print "\tObject is not used in scope.\n";
}
}
findpath
$path = $ccm->findpath($file_spec, $proj_vers);
This is a convenience function. It returns the relative pathname (including the objects's name) for the object $file_spec
within the project $proj_vers
.
Returns undef
if $file_spec
is not used in $proj_vers
or if $file_spec
does not exist.
Example:
$ccm->findpath("main.c-1:csrc:3", "guilib-darcy");
returns
"guilib/sources/main.c"
traverse_project
traverse_project(\&wanted, $project, $dir);
traverse_project(\%options, $project, $dir);
traverse_project
walks the tree below directory $dir
in project $project
without the need for a workarea. It is modelled on File::Find.
&wanted
is a code reference described in "wanted function" below. $project
can be any project specification (in project-version form, an objectname or a VCS::CMSynergy::Object
). However, $dir
must be a VCS::CMSynergy::Object
. If $dir
is omitted, it defaults to the top level directory of $project
.
wanted function
&wanted
is called once for all objects below $dir
including $dir
itself. It will also be called on sub projects of $project
, but traverse_project
will not recurse into sub projects unless the subprojects
flag is specified (see "options" below).
On each call to &wanted
, $_
will be bound to the currently traversed object (a VCS::CMSynergy::Object
).
@VCS::CMSynergy::Traversal::dirs
will be bound to an array of VCS::CMSynergy::Object
s of cvtype "dir" representing the path in $project
project from $dir
to $_
. In particular, @VCS::CMSynergy::Traversal::dirs[-1]
is the parent "dir" of $_
.
Similarly @VCS::CMSynergy::Traversal::projects
represents the sub project hierarchy starting with $project
. In particular, $_
is a member of $VCS::CMSynergy::Traversal::projects[-1]
.
You may set $VCS::CMSynergy::Traversal::prune
to a true value in &wanted
to stop recursion into sub directories (or sub projects) (this makes only sense when &wanted
is called on a "dir or "project" object).
If cwrecursion into sub projects is specfied, &wanted
will be called once for the "project" object and also for the top level "dir" of the sub project.
options
The first argument of traverse_project
may also be a hash reference. The following keys are supported:
wanted
(code reference)-
The value should be a code reference. It is described in "wanted function".
bydepth
(boolean)-
If this option is set,
traverse_project
calls&wanted
on a directory (or project) only after all its entries have been processed. It is "off" by default. preprocess
(code reference)-
The value should be a code reference. It is used to preprocess the children of a dir (or project), i.e. before traverse_project starts traversing it. The preprocessing function is called with a list of
VCS::CMSynergy::Object
s and is expected to return a possibly reordered sub set of this list of children. Note that the list may contain "dir" and "project" objects. When the preprocessing function is called,$_
is bound to the parent object (of type "dir" or "project"). subprojects
(boolean)-
If this option is set,
traverse_project
will recurse into sub projects. It is "off" by default.
Example:
use File::Spec;
...
$ccm->traverse_project(
sub {
print File::Spec->catdir(
map { $_->name } (@VCS::CMSynergy::Traversal::dirs, $_)), "\n"
unless $_->cvtype eq 'project';
},
'toolkit-1.0:project:1');
This prints the directory tree of project toolkit-1.0:project:1 similar to the Unix command find. The order of entries in a directory is unspecified and sub projects are not traversed:
toolkit
toolkit/makefile
toolkit/makefile.pc
toolkit/misc
toolkit/misc/toolkit.ini
toolkit/misc/readme
Another example:
$ccm->traverse_project({
wanted => sub {
return unless $_->cvtype eq 'project';
print " " x @VCS::CMSynergy::Traversal::projects, $_->proj_vers, "\n";
},
preprocess => sub { sort { $a->name cmp $b->name } @_; },
subprojects => 1,
},
'toolkit-1.0:project:1');
This prints the complete project hierarchy rooted at toolkit-1.0:project:1. Only projects are shown, entries are sorted by name and are intended according to their depth:
toolkit-1.0
calculator-1.0
editor-1.0
guilib-1.0
get_attribute
$value = $ccm->get_attribute($attr_name, $file_spec);
Get the value of the attribute $attr_name
for $file_spec
(using (ccm attribute -show).
If RaiseError
is not set and an error occurs (e.g. attribute $attr_name
does not exist on object $file_spec
), undef
will be returned.
Note the following differences from ccm attribute -show:
Only one
$file_spec
is allowed.There is no
-p
(project) option. If you want to get an attribute of a project use the full objectname of the project for$file_spec
.
set_attribute
$ccm->set_attribute($attr_name, $file_spec, $value);
Set the value of the attribute $attr_name
for $file_spec
to $value
(using (ccm attribute -modify).
Returns $value
on success. If RaiseError
is not set and an error occurs (e.g. attribute $attr_name
does not exist on object $file_spec
), undef
will be returned.
This works for all types of attributes, even those of type text (or derived from text) and with $value
s that may contain multiple lines or are of arbitrary length.
Note the following differences from ccm attribute -modify:
Only one
$file_spec
is allowed.There is no
-p
(project) option. If you want to set an attribute of a project use the full objectname of the project for$file_spec
.
create_attribute
$ccm->create_attribute($attr_name, $type, $value, @file_specs);
Create attribute $attr_name
of type $type
on all objects given by @file_specs
(using ccm attribute -create). You may also set an initial value by passing something other than undef
for $value
.
Note the following differences from ccm attribute -create:
There is no
-p
(project) option. If you want to set an attribute of a project use the full objectname of the project for$file_spec
.
FIXME: allow multiple attr_names as in copy_attribute?
delete_attribute
$ccm->delete_attribute($attr_name, @file_specs);
Delete attribute $attr_name
from all objects given by @file_specs
(using ccm attribute -delete).
Note the following differences from ccm attribute -create:
There is no
-p
(project) option. If you want to set an attribute of a project use the full objectname of the project for$file_spec
.
FIXME: allow multiple attr_names as in copy_attribute?
copy_attribute
$ccm->copy_attribute($attr_name, $flags, $from_file_spec, @to_file_specs);
Copy attribute $attr_name
from $from_file_spec
by objects given by @to_file_specs
(using ccm attribute -copy).
You can specify multiple attributes to copy by passing a reference to an array of attribute names as $attr_name
.
$flags
may be undef
or a reference to an array containing a subset of the following strings: "append"
, "subproj"
, "suball"
, e.g.
$ccm->copy_attribute($attr_name, [ qw(subproj suball) ],
"proja-1.0:project:1", "projb-1.0:project:1");
Cf. the CM Synergy documentation on the attribute command for the meaning of these flags.
Note the following differences from ccm attribute -create:
There is no
-p
(project) option. If you want to set an attribute of a project use the full objectname of the project for$file_spec
.
list_attributes
$hash_ref = $ccm->list_attributes($file_spec);
Lists all attributes for $file_spec
(using ccm attribute -la).
Returns a reference to a hash containing pairs of attribute name and attribute type (e.g. string
, time
). Returns undef
in case of error.
Note the following differences from ccm attribute -modify:
Only one
$file_spec
is allowed.
property
$value = $ccm->property($keyword, $file_spec);
Returns the value of property $keyword
for $file_spec
(using ccm properties -f ...). You can use any of the CM Synergy built-in keywords for $keyword
. If the value of $keyword
is undefined, undef
is returned (whereas ccm properties would print it as the string "void
").
types
@types = $ccm->types;
Returns an array of types from ccm show -types.
ls
$ary_ref = $ccm->ls(@args);
Executes the ccm ls command with the given @args
as parameters. The output (as formatted by the -format
option) is split into lines. These are chomped and a reference to the resulting array of strings is returned.
If there was an error, undef
is returned.
Note that you must pass every ccm ls argument or option as a single Perl argument.
If you are interested to obtain the value of several attributes, you should look at the "ls_arrayref" and "ls_hashref" methods that return this information in structured form. If you are only interested in the identity of the listed objects, you should look at the "ls_object" method.
ls_object
$ary_ref = $ccm->ls_object($file_spec);
Lists information about a file or the contents of a directory using the work area name $file_spec
. Returns a reference to an array of corresponding VCS::CMSynergy::Object
s. The default $file_spec
is the working directory.
ls_arrayref
$ary_ref = $ccm->ls_arrayref($file_spec, @keywords);
Lists the values of the built-in keywords or attributes supplied in @keywords
for a file or the contents of a directory Returns a reference to an array of references, one per result row. Each reference points to an array containing the values of the keywords for that particular object (in the order given by @keywords
).
If there was an error, undef
is returned.
If the value of a keyword or an attribute is undefined or the attribute is not present, the actual value of the corresponding array element is undef
(whereas ccm ls would print it as the string "void
").
Note that the keyword or attribute names given in @keywords
should not contain a leading %
. Example:
my $result = $ccm->ls('foo', qw(displayname type modify_time);
foreach my $row (@$result)
{
my ($displayname, $type, $modify_time) = @$row;
print "$displayname ($type) last modified at $modify_time\n";
...
}
ls_hashref
$ary_ref = $ccm->ls_hashref($file_spec, @keywords);
Lists the values of the built-in keywords or attributes supplied in @keywords
for a file or the contents of a directory using the work area name $file_spec
. Returns a reference to an array of references, one per result row. Each reference points to hash containing attribute and value pairs where the keys are @keywords
.
If there was an error, undef
is returned.
If the value of a keyword or an attribute is undefined or the attribute is not present, the actual value of the corresponding hash element is undef
(whereas ccm ls would print it as the string "void
").
Note that the keyword or attribute names given in @keywords
should not contain a leading %
. Example:
my $result = $ccm->ls_hashref('foo', qw(displayname type modify_time);
foreach my $row (@$result)
{
print "$row->{displayname} last modified at $row->{modify_time}\n";
...
}
set
$value = $ccm->set($option);
$old_value = $ccm->set($option, $new_value);
$hash_ref = $ccm->set;
Get or set the value of an option.
In the first form, set
returns the value of $option
. If the option is unset, undef
is returned (whereas ccm set would print "(unset)"
in this case).
In the second form, the $option
is set to $new_value
, the previous value is returned. If $new_value
is undef
, $option
is unset.
In the third form, a reference to a hash is returned. The hash consists of all currently defined options as keys and their respective values.
ccm_with_option and ccm_with_text_editor
($rc, $out, $err) = $ccm->ccm_with_option($option, $value, @cmd);
($rc, $out, $err) = $ccm->ccm_with_text_editor($text_value, @cmd);
These are convenience functions for executing a command that is sensitive to the value of a session option, esp. text_editor.
ccm_with_option
does the following:
saves the old value of
$option
and sets it to$value
with$ccm->set($option, $value);
with the new setting in effect, executes
$ccm->ccm(@cmd);
finally restores the old value of
$option
.
ccm_with_text_editor
is useful in scripting ccm commands like ccm users. These commands usually open a temporary file generated by CM Synergy in a user-specified editor. Then the user edits the contents and save her changes. Finally, CM Synergy reads back the temporary file and does something with the (changed) contents.
ccm_with_text_editor
does the following
creates a temporary file, say
mytmp
, and writes the string$text_value
to it,then executes (on Unix)
$ccm->ccm_with_value(text_editor => "cp mytemp %filename", @cmd);
which causes CM Synergy to accept
$text_value
as the "updated value" w.r.t. to command@cmd
,finally removes the temporary file.
Bot ccm_with_option
and ccm_with_text_editor
return the same value as the inner "ccm" method, except when there is an error setting the new $value
of $option
.
get_releases and set_releases
$releases = $ccm->get_releases;
$ccm->set_releases($releases);
get_releases
fetches the release table (of active releases) as printed by ccm releases -show. It returns a reference to a hash where each key is the release name and the value is (a reference to) a list of included releases, e.g. as formatted by Data::Dumper:
$releases = {
'1.0' => [ qw(1.0) ],
'1.1' => [ qw(1.0 1.1) ],
'2.0' => [ qw(1.0 1.1 2.0) ],
'2.0_SP1' => [ qw(1.0 1.1 2.0 2.0_SP1) ],
'2.1' => [ qw(1.0 1.1 2.0 2.1) ],
'3.0' => [ qw(1.0 1.1 2.0 2.1 3.0) ],
'3.1' => [ qw(1.0 1.1 2.0 2.1 3.0 3.1) ]
};
set_releases
updates the release table. It takes a reference to a hash with the same structure as returned by get_releases
.
ping
if ($ccm->ping) { ... }
ping
tests whether session $ccm
is still alive (without causing an exception).
This could be used e.g. from a web application that keeps a pool of established CM Synergy sessions to deal with user requests: before invoking a command on a session the application must make sure that the session is still valid. If not, it will automatically create a new session.
object
$obj1 = $ccm->object($objectname);
$obj2 = $ccm->object($name, $version, $cvtype, $instance);
Create a VCS::CMSynergy::Object
from either an objectname (sometimes called "object reference form" in CM Synergy documentation) in "name-version:cvtype:instance" format or the four parts specified separately.
This is just a wrapper for "new" in VCS::CMSynergy::Object. However, new
requires the four parts of the objectname to be specified as separate arguments.
Note that no check is made whether the specified object really exists in the database.
set_error
$ccm->set_error($error);
$ccm->set_error($error, $method);
$ccm->set_error($error, $method, $rv, @rv);
Set the "error" value for the session to $error
. This will trigger the normal DBI error handling mechanisms, such as "RaiseError" and "HandleError", if they are enabled. This method is typically only used internally.
The $method
parameter provides an alternate method name for the "RaiseError"/"PrintError" error string. Normally the method name is deduced from caller(1)
.
The "set_error" method normally returns undef
. The $rv
and @rv
parameters provides an alternate return value if "set_error" was called in scalar or in list context, resp.
CLASS METHODS
Note: All class methods can also be invoked on a session object. In most cases this simply means reusing the session's CCM_HOME
and the setting of flags RaiseRrror
and PrintError
.
Actually, all class methods are inherited from VCS::CMSynergy::Client
. Refer to VCS::CMSynergy::Client if you want to use any class methods with different settings of CCM_HOME
in the same invocation of your script.
ccm_command
$last_cmsynergy_command = VCS::CMSynergy->ccm_command;
Returns the last CM Synergy command invoked in any VCS::CMSynergy
session or in any class method.
ccm_home
print "CCM_HOME=", VCS::CMSynergy->ccm_home;
If you didn't fool around with $ENV{CCM_HOME}
, ccm_home
returns just that. Otherwise the answer is more complicated, see VCS::CMSynergy::Client.
error
$last_cmsynergy_error = VCS::CMSynergy->error;
Returns the last error that occured in any VCS::CMSynergy
session or in any class method.
ps
$ary_ref = VCS::CMSynergy->ps;
$ary_ref = VCS::CMSynergy->ps(user => "jdoe", process => "gui_interface", ...);
Executes ccm ps and returns a reference to an array of references, one per CM Synergy process. Each reference points to a hash containing pairs of field names (e.g. host
, database
, pid
) and values for that particular process as listed by ccm ps.
The available keys vary with the type of the process (e.g. engine
, gui_interface
). The process type is listed under key process
. The key rfc_address
is always present. The object registrar (i.e. the unique process with key process
equal to "objreg") has a special key db
. Its value is a reference to an array of database names that the registrar as encountered during its lifetime.
In the second form of invocation, you can pass pairs of field name and field value and ps
will only return processes whose fields match all the corresponding values. Note that in contrast to the ccm ps command, you can filter on multiple fields simultaneously.
Here's an example of the value returned by ps
as formatted by Data::Dumper:
$ps = [
{
'process' => 'router',
'host' => 'tiv01',
'rfc_address' => 'tiv01:5415:160.50.76.15',
'user' => 'ccm_root',
'host_addr' => '',
'pid' => '9428'
},
{
'process' => 'gui_interface',
'database' => '/ccmdb/tbd/slc/db',
'engine_address' => 'tiv01:60682:160.50.76.15',
'host' => 'lapis',
'user' => 'q076273',
'msg_handler_1' => 'uissys:message_handler',
'display' => '',
'callback' => 'vistartup:cb_init',
'rfc_address' => 'lapis:1934:160.50.136.36',
'pid' => '224',
'host_addr' => ''
},
{
'process' => 'cmd_interface',
'database' => '/ccmdb/tbd/nasa_ix/db',
'engine_address' => 'nasaora:1559:160.48.78.33',
'host' => 'nasaora',
'user' => 'qx06322',
'msg_handler_1' => 'uissys:message_handler',
'display' => 'nasaix11:0',
'callback' => 'ciserver:cb_init',
'rfc_address' => 'nasaora:1556:160.48.78.33',
'pid' => '24367',
'host_addr' => ''
},
{
'process' => 'engine',
'database' => '/ccmdb/tbd/nasa_ix/db',
'host' => 'nasaora',
'user' => 'qx06322',
'callback' => 'engine_startup:cb_init',
'rfc_address' => 'nasaora:1559:160.48.78.33',
'pid' => '24490',
'host_addr' => '',
'ui_address' => 'nasaora:1556:160.48.78.33'
},
{
'process' => 'objreg',
'db' => [
'/ccmdb/tbd/nasa_ix/db',
'/ccmdb/tbd/slc/db',
'/ccmdb/tbd/eai/db',
],
'max_conns' => '256',
'objreg_machine_addr' => '160.50.76.15',
'host' => 'tiv01',
'user' => 'ccm_root',
'callback' => 'objreg:cb_init',
'policy' => 'one_per_db',
'noblock' => 'true',
'rfc_address' => 'tiv01:60352:160.50.76.15',
'objreg_machine' => 'tiv01',
'host_addr' => '',
'pid' => '9896',
'objreg_machine_hostname' => 'tiv01'
},
...
];
status
$ary_ref = VCS::CMSynergy->status;
Executes ccm status and returns a reference to an array of references, one per CM Synergy session. Each reference points to a hash containing pairs of field names (e.g. database
) and values for that particular session.
The available keys are a subset of the keys returned by the "ps" method: rfc_address
, database
, user
, and process
. There is an additional key current
with a boolean value marking CM Synergy's notion of the current session.
Note: Unlike the output of the ccm status command, the value for database
has a trailing "/db"
. This makes it consistent with the session attribute database
and the return value of "ps".
Here's an example of the value returned by status
as formatted by Data::Dumper:
$status = [
{
'process' => 'gui_interface',
'database' => '/ccmdb/scm/support/db',
'current' => '1',
'rfc_address' => 'tiv01:53020:160.50.76.15',
'user' => 'qx06959'
},
{
'process' => 'gui_interface',
'database' => '/ccmdb/scm/support/db',
'current' => '',
'rfc_address' => 'wmuc111931:4661:160.50.136.201',
'user' => 'qx06959'
},
{
'process' => 'cmd_interface',
'database' => '/ccmdb/test/tut51/db',
'current' => '',
'rfc_address' => 'tiv01:53341:160.50.76.15',
'user' => 'qx06959'
}
];
version
($full_version, $schema, $informix, @patches) = VCS::CMSynergy->version;
$version = VCS::CMSynergy->version;
Returns version info about the CM Synergy installation. In a scalar context version
returns the (short) CM Synergy version number, e.g. "6.2". In an array context the following information is returned:
the full CM Synergy version
the database schema version
the Informix version
a possible empty array of applied CM Synergy patches
trace
VCS::CMSynergy->trace($trace_level);
VCS::CMSynergy->trace($trace_level, $trace_filename);
This method enables trace information to be written.
Trace levels $trace_level
are as follows:
- 0
-
trace disabled
- 1
-
trace session start/stop; show parameters and exit code for all invocations of CMSynergy CLI
- 2
-
trace method autoloading; show queries synthesized from shortcuts
- 8
-
show complete output for all invocations of CMSynergy CLI
Initially trace output is written to STDERR
. If $trace_filename
is specified and can be opened in append mode then all trace output is redirected to that file. A warning is generated irfs the file can't be opened. Further calls to trace
without a $trace_filename
do not alter where the trace output is sent. If $trace_filename
is undefined, then trace output is sent to STDERR
and the previous trace file is closed.
The trace
method returns the previous tracelevel.
See also "trace_msg".
You can also enable the same trace information by setting the CMSYNERGY_TRACE
environment variable before starting Perl.
On Unix-like systems using a Bourne-like shell, you can do this easily on the command line:
CMSYNERGY_TRACE=2 perl your_test_script.pl
If CMSYNERGY_TRACE
is set to a non-numeric value, then it is assumed to be a file name and the trace level will be set to 2 with all trace output appended to that file. If the name begins with a number followed by an equal sign (=
), then the number and the equal sign are stripped off from the name, and the number is used to set the trace level. For example:
CMSYNERGY_TRACE=1=trace.log perl your_test_script.pl
trace_msg
VCS::CMSynergy->trace_msg($message_text);
VCS::CMSynergy->trace_msg($message_text, $min_level);
Writes $message_text
to the trace file if trace is enabled. See "trace".
If $min_level
is defined, then the message is output only if the trace level is equal to or greater than that level. $min_level
defaults to 1.
databases
@databases = VCS::CMSynergy->databases;
@databases = VCS::CMSynergy->databases($servername);
Returns an array containing the names of all known CM Synergy databases.
Note: This method does not work on Windows.
hostname
The hostname as returned by ccm_hostname.
TODO
anything else?
SEE ALSO
VCS::CMSynergy::Users, VCS::CMSynergy::Object, VCS::CMSynergy::Client
AUTHORS
Roderich Schupp, argumentum GmbH <schupp@argumentum.de>
COPYRIGHT AND LICENSE
The VCS::CMSynergy module is Copyright (c) 2001-2003 argumentum GmbH, http://www.argumentum.de. All rights reserved.
You may distribute it under the terms of either the GNU General Public License or the Artistic License, as specified in the Perl README file.
4 POD Errors
The following errors were encountered while parsing the POD:
- Around line 2711:
You forgot a '=back' before '=head2'
- Around line 2726:
Expected text after =item, not a number
- Around line 2731:
Expected text after =item, not a number
- Around line 2735:
Expected text after =item, not a number