NAME JIRA::REST::Class - An OO Class module built atop "JIRA::REST" for dealing with JIRA issues and their data as objects. VERSION version 0.03 SYNOPSIS use JIRA::REST::Class; my $jira = JIRA::REST::Class->new({ url => 'https://jira.example.net', username => 'myuser', password => 'mypass', SSL_verify_none => 1, # if your server uses self-signed SSL certs }); # get issue by key my ($issue) = $jira->issues('MYPROJ-101'); # get multiple issues by key my @issues = $jira->issues('MYPROJ-101', 'MYPROJ-102', 'MYPROJ-103'); # get multiple issues through search my @issues = $jira->issues({ jql => q/project = "MYPROJ" and status = "open"/ }); # get an iterator for a search my $search = $jira->iterator({ jql => q/project = "MYPROJ" and status = "open"/ }); if ( $search->issue_count ) { printf "Found %d open issues in MYPROJ:\n", $search->issue_count; while ( my $issue = $search->next ) { printf " Issue %s is open\n", $issue->key; } } else { print "No open issues in MYPROJ.\n"; } DESCRIPTION An OO Class module built atop "JIRA::REST" for dealing with JIRA issues and their data as objects. This code is a work in progress, so it's bound to be incomplete. I add methods to it as I discover I need them. I have also coded for fields that might exist in my JIRA server's configuration but not in yours. It is my *intent*, however, to make things more generic as I go on so they will "just work" no matter how your server is configured. I'm actively working with the author of "JIRA::REST" (thanks gnustavo!) to keep the arguments for "JIRA::REST::Class->new" exactly the same as "JIRA::REST->new", so I'm just duplicating the documentation for "JIRA::REST->new": CONSTRUCTOR new *HASHREF* new *URL*, *USERNAME*, *PASSWORD*, *REST_CLIENT_CONFIG*, *ANONYMOUS*, *PROXY*, *SSL_VERIFY_NONE* The constructor can take its arguments from a single hash reference or from a list of positional parameters. The first form is preferred because it lets you specify only the arguments you need. The second form forces you to pass undefined values if you need to pass a specific value to an argument further to the right. The arguments are described below with the names which must be used as the hash keys: * url A string or a URI object denoting the base URL of the JIRA server. This is a required argument. The REST methods described below all accept as a first argument the endpoint's path of the specific API method to call. In general you can pass the complete path, beginning with the prefix denoting the particular API to use ("/rest/api/VERSION", "/rest/servicedeskapi", or "/rest/agile/VERSION"). However, to make it easier to invoke JIRA's Core API if you pass a path not starting with "/rest/" it will be prefixed with "/rest/api/latest" or with this URL's path if it has one. This way you can choose a specific version of the JIRA Core API to use instead of the latest one. For example: my $jira = JIRA::REST::Class->new({ url => 'https://jira.example.net/rest/api/1', }); * username * password The username and password of a JIRA user to use for authentication. If anonymous is false then, if either username or password isn't defined the module looks them up in either the ".netrc" file or via Config::Identity (which allows "gpg" encrypted credentials). Config::Identity will look for ~/.jira-identity or ~/.jira. You can change the filename stub from "jira" to a custom stub with the "JIRA_REST_IDENTITY" environment variable. * rest_client_config A JIRA::REST object uses a REST::Client object to make the REST invocations. This optional argument must be a hash reference that can be fed to the REST::Client constructor. Note that the "url" argument overwrites any value associated with the "host" key in this hash. As an extension, the hash reference also accepts one additional argument called proxy that is an extension to the REST::Client configuration and will be removed from the hash before passing it on to the REST::Client constructor. However, this argument is deprecated since v0.017 and you should avoid it. Instead, use the following argument instead. * proxy To use a network proxy set this argument to the string or URI object describing the fully qualified URL (including port) to your network proxy. * ssl_verify_none Sets the "SSL_verify_mode" and "verify_hostname ssl" options on the underlying REST::Client's user agent to 0, thus disabling them. This allows access to JIRA servers that have self-signed certificates that don't pass LWP::UserAgent's verification methods. * anonymous Tells the module that you want to connect to the specified JIRA server with no username or password. This way you can access public JIRA servers without needing to authenticate. METHODS issues QUERY issues KEY [, KEY...] The "issues" method can be called two ways: either by providing a list of issue keys, or by proving a single hash reference which describes a JIRA query in the same format used by "JIRA::REST" (essentially, jql => "JQL query string"). The return value is an array of "JIRA::REST::Class::Issue" objects. query QUERY The "query" method takes a single parameter: a hash reference which describes a JIRA query in the same format used by "JIRA::REST" (essentially, jql => "JQL query string"). The return value is a single "JIRA::REST::Class::Query" object. iterator QUERY The "query" method takes a single parameter: a hash reference which describes a JIRA query in the same format used by "JIRA::REST" (essentially, jql => "JQL query string"). It accepts an additional field, however: restart_if_lt_total. If this field is set to a true value, the iterator will keep track of the number of results fetched and, if when the results run out this number doesn't match the number of results predicted by the query, it will restart the query. This is particularly useful if you are transforming a number of issues through an iterator, and the transformation causes the issues to no longer match the query. The return value is a single "JIRA::REST::Class::Iterator" object. The issues returned by the query can be obtained in serial by repeatedly calling next on this object, which returns a series of "JIRA::REST::Class::Issue" objects. maxResults An accessor that allows setting a global default for maxResults. Defaults to 50. issue_types Returns a list of defined issue types (as "JIRA::REST::Class::Issue::Type" objects) for this server. projects Returns a list of projects (as "JIRA::REST::Class::Project" objects) for this server. project PROJECT_ID || PROJECT_KEY || PROJECT_NAME Returns a "JIRA::REST::Class::Project" object for the project specified. Returns undef if the project doesn't exist. SSL_verify_none Disables the SSL options SSL_verify_mode and verify_hostname on the user agent used by this class' "REST::Client" object. name_for_user When passed a scalar that could be a "JIRA::REST::Class::User" object, returns the name of the user if it is a "JIRA::REST::Class::User" object, or the unmodified scalar if it is not. key_for_issue When passed a scalar that could be a "JIRA::REST::Class::Issue" object, returns the key of the issue if it is a "JIRA::REST::Class::Issue" object, or the unmodified scalar if it is not. find_link_name_and_direction When passed two scalars, one that could be a "JIRA::REST::Class::Issue::LinkType" object and another that is a direction (inward/outward), returns the name of the link type and direction if it is a "JIRA::REST::Class::Issue::LinkType" object, or attempts to determine the link type and direction from the provided scalars. dump Returns a stringified representation of the object's data generated somewhat by Data::Dumper::Concise, but only going one level deep. If it finds objects in the data, it will attempt to represent them in some abbreviated fashion which may not display all the data in the object. INTERNAL METHODS get URL [, QUERY] A wrapper for "JIRA::REST"'s GET method. post Wrapper around "JIRA::REST"'s POST method. put Wrapper around "JIRA::REST"'s PUT method. delete Wrapper around "JIRA::REST"'s DELETE method. data_upload Similar to "JIRA::REST->attach_files", but entirely from memory and only attaches one file at a time. Takes the following named parameters: + url The relative URL to POST to. This will have the hostname and REST version information prepended to it, so all you need to provide is something like "/issue/"*issueIdOrKey*"/attachments". I'm allowing the URL to be specified in case I later discover something this can be used for besides attaching files to issues. + name The name that is specified for this file attachment. + data The actual data to be uploaded. If a reference is provided, it will be dereferenced before posting the data. I guess that makes it only a *little* like "JIRA::REST->attach_files"... rest_api_url_base Returns the base URL for this JIRA server's REST API. strip_protocol_and_host A method to take the provided URL and strip the protocol and host from it. url An accessor for the URL passed to the "JIRA::REST" object. username An accessor for the username passed to the "JIRA::REST" object. password An accessor for the password passed to the "JIRA::REST" object. rest_client_config An accessor for the REST client config passed to the "JIRA::REST" object. jira Returns a "JIRA::REST::Class" object with credentials for the last JIRA user. factory An accessor for the "JIRA::REST::Class::Factory". JIRA_REST An accessor that returns the "JIRA::REST" object being used. REST_CLIENT An accessor that returns the "REST::Client" object inside the "JIRA::REST" object being used. make_object A pass-through method that calls "JIRA::REST::Class::Factory::make_object()". make_date A pass-through method that calls "JIRA::REST::Class::Factory::make_date()". class_for A pass-through method that calls "JIRA::REST::Class::Factory::get_factory_class()". obj_isa When passed a scalar that could be an object and a class string, returns whether the scalar is, in fact, an object of that class. Looks up the actual class using "class_for()", which calls "JIRA::REST::Class::Factory::get_factory_class()". deep_copy *THING* Returns a deep copy of the hashref it is passed Example: my $bar = Class->deep_copy($foo); $bar->{XXX} = 'new value'; # $foo->{XXX} isn't changed shallow_copy *THING* A utility function to produce a shallow copy of a thing (mostly not going down into the contents of objects within objects). SEE ALSO * JIRA::REST "JIRA::REST::Class" uses "JIRA::REST" to perform all its interaction with JIRA. * REST::Client "JIRA::REST" uses a "REST::Client" object to perform its low-level interactions. * JIRA REST API Reference Atlassian's official JIRA REST API Reference. REPOSITORY CREDITS Gustavo Leite de Mendonça Chaves Many thanks to Gustavo for "JIRA::REST", which is what I started working with when I first wanted to automate my interactions with JIRA in the summer of 2016, and without which I would have had a LOT of work to do. AUTHOR Packy Anderson CONTRIBUTOR Alexey Melezhik COPYRIGHT AND LICENSE This software is Copyright (c) 2016 by Packy Anderson. This is free software, licensed under: The Artistic License 2.0 (GPL Compatible)