The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Net::Gnats - Perl interface to GNU Gnats daemon

VERSION

0.22

DESCRIPTION

Net::Gnats provides a perl interface to the gnatsd command set. Although most of the gnatsd command are present and can be explicitly called through Net::Gnats, common gnats tasks can be accompished through some methods which simplify the process (especially querying the database, editing bugs, etc).

SYNOPSIS

  use Net::Gnats;

  # Instantiates object with Gnats hostname 'localhost' and port '1529'.
  my $g = Net::Gnats->new;

  # Creates the session between Net::Gnats and the gnatsd process.
  say 'Connected.' if $g->gnatsd_connect;

  # Retrieves the list of databases hosted by the server.  Typically,
  # it's the only command that can be performed without logging in.
  my $db_names = $g->get_dbnames;

  $g->login("default","somedeveloper","password");

  # Change field values in Gnats immediately by using the replaceField
  # method.

  my $pr = $g->get_pr_by_number(2);
  $pr->replaceField('Synopsis', 'The New Synopsis String');
  $pr->replaceField('Responsible', 'joe', q|Because It's Joe's|);

  # Change field values and submit the PR for update.  This is the
  # preferred method if many fields require updating.

  my $pr = $g->get_pr_by_number(3);
  $pr->setField('Synopsis', 'The New Synopsis String');
  $pr->setField('Responsible', 'joe', q|Because It's Joe's|);
  $g->update_pr($pr);

  my $new_pr = $g->new_pr();
  $new_pr->setField("Submitter-Id","developer");
  $g->submitPR($new_pr);

  # Close the session.  The session will close abruptly if the program
  # simply exits.

  $g->disconnect;

COMMON TASKS

VIEWING DATABASES

Fetching database names is the only action that can be done on a Gnats object before logging in via the login() method.

  my $g = Net::Gnats->new;
  $g->gnatsd_connect;
  my @dbNames = $g->getDBNames;

Note that getDBNames() is different than listDatabases(), which requires logging in first and gets a little more info than just names.

LOGGING IN TO A DATABASE

The Gnats object has to be logged into a database to perform almost all actions.

  my $g = Net::Gnats->new;
  $g->gnatsd_connect;
  $g->login("default","myusername","mypassword");

SUBMITTING A NEW PR

The Net::Gnats::PR object acts as a container object to store information about a PR (new or otherwise). A new PR is submitted to gnatsperl by constructing a PR object.

  my $pr = $g->new_pr;
  $pr->setField("Submitter-Id","developer");
  $pr->setField("Originator","Doctor Wifflechumps");
  $pr->setField("Organization","GNU");
  $pr->setField("Synopsis","Some bug from perlgnats");
  $pr->setField("Confidential","no");
  $pr->setField("Severity","serious");
  $pr->setField("Priority","low");
  $pr->setField("Category","gnatsperl");
  $pr->setField("Class","sw-bug");
  $pr->setField("Description","Something terrible happened");
  $pr->setField("How-To-Repeat","Like this.  Like this.");
  $pr->setField("Fix","Who knows");
  $g->submit_pr($pr);

Obviously, fields are dependent on a specific gnats installation, since Gnats administrators can rename fields and add constraints. There are some methods in Net::Gnats to discover field names and constraints, all described below.

Instead of setting each field of the PR individually, the setFromString() method is available. The string that is passed to it must be formatted in the way Gnats handles the PRs. This is useful when handling a Gnats email submission ($pr->setFromString($email)) or when reading a PR file directly from the database. See Net::Gnats::PR for more details.

QUERYING THE PR DATABASE

  my $prNums = $g->query('Number>"12"', "Category=\"$thisCat\"");
  print "Found " . join(":", @$prNums ) . " matching PRs \n";

Pass a list of query expressions to query(). A list of PR numbers of matching PRs is returned. You can then pull out each PR as described next.

FETCHING A PR

  my $prnum = 23;
  my $PR = $g->get_pr_by_number($prnum);
  print $PR->getField('synopsis');
  print $PR->asString();

The method get_pr_by_number() will return a Net::Gnats::PR object corresponding to the PR num that was passed to it. The getField() and asString() methods are documented in Net::Gnats::PR, but I will note here that asString() returns a string in the proper Gnats format, and can therefore be submitted directly to Gnats via email or saved to the db directory for instance. Also:

 $pr->setFromString($oldPR->asString() );

 works fine and will result in a duplicate of the original PR object.

MODIFYING A PR

There are 2 methods of modifying fields in a Net::Gnats::PR object.

The first is to use the replaceField() or appendField() methods which uses the gnatsd REPL and APPN commands. This means that the changes to the database happen immediatly.

  my $prnum = 23;
  my $PR = $g->get_pr_by_number($prnum);
  if (! $PR->replaceField('Synopsis','New Synopsis')) {
    warn "Error replacing field (" . $g->get_error_message . ")\n";
  }

If the field requires a change reason, it must be supplied as the 3rd argument.

  $PR->replaceField('Responsible','joe',"It's joe's problem");

The second is to use the setField() and updatePR() methods which uses the gnatsd EDIT command. This should be used when multiple fields of the same PR are being changed, since the datbase changes occur at the same time.

  my $prnum = 23;
  my $PR = $g->get_pr_by_number($prnum);
  $PR->setField('Synopsis','New Synopsis');
  $PR->setField('Responsible','joe',"It's joe's problem");
  if (! $g->updatePR($PR) ) {
    warn "Error updating $prNum: " . $g->get_error_message . "\n";
  }

CONSTRUCTOR

new

Constructor, optionally taking one or two arguments of hostname and port of the target gnats server. If not supplied, the hostname defaults to localhost and the port to 1529.

ACCESSORS

current_session

Exported function.

Retrieves the currently used session (last initialized).

skip_version_check

If you are using a custom gnats daemon, your version number might "not be supported". If you are sure you know what you are doing and am willing to take the consequences:

 my $g = Net::Gnats->new();
 $g->skip_version_check(1);

session

Retrieve the session currently in effect. Used for Net::Gnats instantiated objects only.

 my $session = $g->session;

verbose

Sets verbose on. By default, verbose is off. The default setting is optimized for headless execution.

To turn verbose on, change to 1.

verbose_level

Sets the verbose level. The levels are:

 0: No level (based on verbose being on)
 1: Brief error, displays Gnats error codes.
 2: Detailed error, displays Gnats error codes and any messages.
 3: Trace, full code path walking.

METHODS

gnatsd_connect

Connects to the gnats server. No arguments. Returns true if successfully connected, false otherwise.

disconnect

Issues the QUIT command to the Gnats server, thereby closing the connection.

Although the Gnats documentation says there is not a failure case for this command, it responds true/false accordingly.

 $g->disconnect;

get_dbnames

Issues the DBLS command, and returns a list of database names in the gnats server. Unlike listDatabases, one does not need to use the logn method before using this method.

 my $list = $g->get_dbnames;

list_databases

Issues the LIST DATABASES command, and returns a list of hashrefs with keys 'name', 'desc', and 'path'.

list_categories

Issues the LIST CATEGORIES command, and returns a list of hashrefs with keys 'name', 'desc', 'contact', and '?'.

list_submitters

Issues the LIST SUBMITTERS command, and returns a list of hashrefs with keys 'name', 'desc', 'contract', '?', and 'responsible'.

 my $s = $gnats->list_submitters;

list_responsible

Issues the LIST RESPONSIBLE command, and returns a list of hashrefs with keys 'name', 'realname', and 'email'.

list_states

Issues the LIST STATES command, and returns a list of hashrefs with keys 'name', 'type', and 'desc'.

list_fieldnames

Issues the LIST FIELDNAMES command, and returns a list of hashrefs with key 'name'.

Protocol: returns an anonymous array of field names.

list_inputfields_initial

Issues the LIST INITIALINPUTFIELDS command, and returns a list of hashrefs with key 'name'.

get_field_type

Expects a single fieldname or an anonymous array of field types.

Returns 0 if the type information could not be retrieved.

Returns a list of types based on the number of fields passed.

get_field_type_info

Expects a fieldname and property as arguments, and issues the FTYPINFO command. Returns text response or undef if error.

get_field_desc

Expects a fieldname as sole argument, and issues the FDSC command. Returns text response or undef if error.

get_field_flags

Expects a fieldname as sole argument, and issues the FIELDFLAGS command. Returns text response or undef if error.

get_field_validators

Expects a fieldname as sole argument, and issues the FVLD command. Returns text response or undef if error.

validate_field

Expects a Net::Gnats::FieldInstance object, and issues the VFLD command. Returns true if propose value is acceptable, false otherwise.

 $g->validate_field(Net::Gnats::FieldInstance->new(name => 'Originator', value => 'rich'));

get_field_default

Expects a fieldname as sole argument, and issues the INPUTDEFAULT command. Returns text response or undef if error.

reset_server

Issues the RSET command, returns true if successful, false otherwise.

lock_main_database

Issues the LKDB command, returns true if successful, false otherwise.

unlock_main_database

Issues the UNDB command, returns true if successful, false otherwise.

lock_pr

Expects a PR number and user name as arguments, and issues the LOCK command. Returns true if PR is successfully locked, false otherwise.

NEW: Note that the response content has the PR. If you would like the PR from this response:

 my $s = $gnats->session;
 $s->issue(Net::Gnats::Command->lock_pr( ... ))->response->as_list;

unlock_pr

Expects a PR number a sole argument, and issues the UNLK command. Returns true if PR is successfully unlocked, false otherwise.

delete_pr($pr)

Expects a PR number a sole argument, and issues the DELETE command. Returns true if PR is successfully deleted, false otherwise.

check_pr

Expects the text representation of a PR (see COMMON TASKS above) as input and issues the CHEK initial command. Returns true if the given PR is a valid entry, false otherwise.

set_workingemail

Expects an email address as sole argument, and issues the EDITADDR command. Returns true if email successfully set, false otherwise.

truncate_field_content

Expects a PR number, a fieldname, a replacement value, and optionally a changeReason value as arguments, and issues the REPL command. Returns true if field successfully replaced, false otherwise.

If the field has requireChangeReason attribute, then the changeReason must be passed in, otherwise the routine will return false.

replaceField changes happen immediatly in the database. To change multiple fields in the same PR it is more efficiant to use updatePR.

append_field_content

Expects a PR number, a fieldname, and a append value as arguments, and issues the APPN command. Returns true if field successfully appended to, false otherwise.

submit_pr

Expect a Gnats::PR object as sole argument, and issues the SUMB command. Returns true if PR successfully submitted, false otherwise.

DEPRECATION NOTICE: This method will be deprecated soon. Please be aware that you can submit a PR from a PR object.

 $pr = $pr->submit;

And $pr will contain the new PR number. See PR.pm for details.

update_pr

Expect a Gnats::PR object as sole argument, and issues the EDIT command. Returns true if PR successfully submitted, false otherwise.

Use this instead of replace_field if more than one field has changed.

new_pr

returns undef if the session is not initialized.

get_pr_by_number()

Expects a number as sole argument. Returns a Gnats::PR object.

query()

Expects one or more query expressions as argument(s). Returns an anonymous array of PR numbers.

If there is an error, then it will return an empty set.

login

Expects a database name, user name, and password as arguments and issues the CHDB command. Returns true if successfully logged in, false otherwise.

 my $g = Net::Gnats->new;
 $g->login('mydb', 'joe', 'joepass');

get_access_mode

Returns the current access mode of the gnats database. Either "edit", "view", or undef;

DIAGNOSTICS

Most methods will return undef if a major error is encountered.

The most recent error codes and messages which Net::Gnats encounters while communcating with gnatsd are stored, and can be accessed with the get_error_code() and get_error_message() methods.

INCOMPATIBILITIES

This library is not compatible with the Gnats protocol prior to GNATS 4.

BUGS AND LIMITATIONS

Bug reports are very welcome. Please submit to the project page (noted below).

CONFIGURATION AND ENVIRONMENT

No externalized configuration or environment at this time.

DEPENDENCIES

No runtime dependencies other than the Perl core at this time.

AUTHOR

Current Maintainer: Richard Elberger riche@cpan.org

Original Author: Mike Hoolehan, <lt>mike@sycamore.us<gt>

Contributions By: Jim Searle, <lt>jims2@cox.net<gt> Project hosted at sourceforge, at http://gnatsperl.sourceforge.net

LICENSE AND COPYRIGHT

Copyright (c) 2014, Richard Elberger. All Rights Reserved.

Copyright (c) 1997-2003, Mike Hoolehan. All Rights Reserved.

This module is free software. It may be used, redistributed, and/or modified under the same terms as Perl itself.