module Octokit
class Client
# Methods for the Issues API
#
# @see https://developer.github.com/v3/issues/
module Issues
# List issues for the authenticated user or repository
#
# @param repository [Integer, String, Repository, Hash] A GitHub repository.
# @param options [Sawyer::Resource] A customizable set of options.
# @option options [Integer] :milestone Milestone number.
# @option options [String] :state (open) State: open, closed, or all.
# @option options [String] :assignee User login.
# @option options [String] :creator User login.
# @option options [String] :mentioned User login.
# @option options [Array] :labels List of Label names. Example: ['bug', 'ui', '@high'].
# @option options [String] :sort (created) Sort: created, updated, or comments.
# @option options [String] :direction (desc) Direction: asc or desc.
# @option options [Integer] :page (1) Page number.
# @return [Array] A list of issues for a repository.
# @see https://developer.github.com/v3/issues/#list-issues-for-a-repository
# @see https://developer.github.com/v3/issues/#list-issues
# @example List issues for a repository
# Octokit.list_issues("sferik/rails_admin")
# @example List issues for the authenticated user across repositories
# @client = Octokit::Client.new(:login => 'foo', :password => 'bar')
# @client.list_issues
def list_issues(repository = nil, options = {})
path = repository ? "#{Repository.new(repository).path}/issues" : "issues"
paginate path, options
end
alias :issues :list_issues
# List all issues across owned and member repositories for the authenticated user
#
# @param options [Sawyer::Resource] A customizable set of options.
# @option options [String] :filter (assigned) State: assigned, created, mentioned, subscribed or closed.
# @option options [String] :state (open) State: open, closed, or all.
# @option options [Array] :labels List of Label names. Example: ['bug', 'ui', '@high'].
# @option options [String] :sort (created) Sort: created, updated, or comments.
# @option options [String] :direction (desc) Direction: asc or desc.
# @option options [Integer] :page (1) Page number.
# @option options [String] :since Timestamp in ISO 8601
# format: YYYY-MM-DDTHH:MM:SSZ
# @return [Array] A list of issues for a repository.
# @see https://developer.github.com/v3/issues/#list-issues
# @example List issues for the authenticated user across owned and member repositories
# @client = Octokit::Client.new(:login => 'foo', :password => 'bar')
# @client.user_issues
def user_issues(options = {})
paginate 'user/issues', options
end
# List all issues for a given organization for the authenticated user
#
# @param org [String, Integer] Organization GitHub login or id.
# @param options [Sawyer::Resource] A customizable set of options.
# @option options [String] :filter (assigned) State: assigned, created, mentioned, subscribed or closed.
# @option options [String] :state (open) State: open, closed, or all.
# @option options [Array] :labels List of Label names. Example: ['bug', 'ui', '@high'].
# @option options [String] :sort (created) Sort: created, updated, or comments.
# @option options [String] :direction (desc) Direction: asc or desc.
# @option options [Integer] :page (1) Page number.
# @option options [String] :since Timestamp in ISO 8601
# format: YYYY-MM-DDTHH:MM:SSZ
# @return [Array] A list of issues.
# @see https://developer.github.com/v3/issues/#list-issues
# @example List all issues for a given organization for the authenticated user
# @client = Octokit::Client.new(:login => 'foo', :password => 'bar')
# @client.org_issues("octokit")
def org_issues(org, options = {})
paginate "#{Organization.path org}/issues", options
end
# Create an issue for a repository
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param title [String] A descriptive title
# @param body [String] An optional concise description
# @param options [Hash] A customizable set of options.
# @option options [String] :assignee User login.
# @option options [Integer] :milestone Milestone number.
# @option options [String] :labels List of comma separated Label names. Example: bug,ui,@high.
# @return [Sawyer::Resource] Your newly created issue
# @see https://developer.github.com/v3/issues/#create-an-issue
# @example Create a new Issues for a repository
# Octokit.create_issue("sferik/rails_admin", 'Updated Docs', 'Added some extra links')
def create_issue(repo, title, body = nil, options = {})
options[:labels] = case options[:labels]
when String
options[:labels].split(",").map(&:strip)
when Array
options[:labels]
else
[]
end
parameters = { :title => title }
parameters[:body] = body unless body.nil?
post "#{Repository.path repo}/issues", options.merge(parameters)
end
alias :open_issue :create_issue
# Get a single issue from a repository
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param number [Integer] Number ID of the issue
# @return [Sawyer::Resource] The issue you requested, if it exists
# @see https://developer.github.com/v3/issues/#get-a-single-issue
# @example Get issue #25 from octokit/octokit.rb
# Octokit.issue("octokit/octokit.rb", "25")
def issue(repo, number, options = {})
get "#{Repository.path repo}/issues/#{number}", options
end
# Close an issue
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param number [Integer] Number ID of the issue
# @param options [Hash] A customizable set of options.
# @option options [String] :assignee User login.
# @option options [Integer] :milestone Milestone number.
# @option options [Array] :labels List of Label names. Example: ['bug', 'ui', '@high'].
# @return [Sawyer::Resource] The updated Issue
# @see https://developer.github.com/v3/issues/#edit-an-issue
# @example Close Issue #25 from octokit/octokit.rb
# Octokit.close_issue("octokit/octokit.rb", "25")
def close_issue(repo, number, options = {})
patch "#{Repository.path repo}/issues/#{number}", options.merge({:state => "closed"})
end
# Reopen an issue
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param number [Integer] Number ID of the issue
# @param options [Hash] A customizable set of options.
# @option options [String] :assignee User login.
# @option options [Integer] :milestone Milestone number.
# @option options [Array] :labels List of Label names. Example: ['bug', 'ui', '@high'].
# @return [Sawyer::Resource] The updated Issue
# @see https://developer.github.com/v3/issues/#edit-an-issue
# @example Reopen Issue #25 from octokit/octokit.rb
# Octokit.reopen_issue("octokit/octokit.rb", "25")
def reopen_issue(repo, number, options = {})
patch "#{Repository.path repo}/issues/#{number}", options.merge({:state => "open"})
end
# Update an issue
#
# @overload update_issue(repo, number, title, body, options)
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param number [Integer] Number ID of the issue
# @param title [String] Updated title for the issue
# @param body [String] Updated body of the issue
# @param options [Hash] A customizable set of options.
# @option options [String] :assignee User login.
# @option options [Integer] :milestone Milestone number.
# @option options [String] :labels List of comma separated Label names. Example: bug,ui,@high.
# @option options [String] :state State of the issue. open or closed
#
# @overload update_issue(repo, number, options)
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param number [Integer] Number ID of the issue
# @param options [Hash] A customizable set of options.
# @option options [String] :title Updated title for the issue
# @option options [String] :body Updated body of the issue
# @option options [String] :assignee User login.
# @option options [Integer] :milestone Milestone number.
# @option options [Array] :labels List of Label names. Example: ['bug', 'ui', '@high'].
# @option options [String] :state State of the issue. open or closed
# @return [Sawyer::Resource] The updated Issue
# @see https://developer.github.com/v3/issues/#edit-an-issue
#
# @example Change the title of Issue #25
# Octokit.update_issue("octokit/octokit.rb", "25", "A new title", "the same body")
#
# @example Change only the assignee of Issue #25
# Octokit.update_issue("octokit/octokit.rb", "25", :assignee => "pengwynn")
def update_issue(repo, number, *args)
arguments = Arguments.new(args)
opts = arguments.options
if arguments.length > 0
opts[:title] = arguments.shift
opts[:body] = arguments.shift
end
patch "#{Repository.path repo}/issues/#{number}", opts
end
# Get all comments attached to issues for the repository
#
# By default, Issue Comments are ordered by ascending ID.
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param options [Hash] Optional parameters
# @option options [String] :sort created or updated
# @option options [String] :direction asc or desc. Ignored without sort
# parameter.
# @option options [String] :since Timestamp in ISO 8601
# format: YYYY-MM-DDTHH:MM:SSZ
#
# @return [Array] List of issues comments.
#
# @see https://developer.github.com/v3/issues/comments/#list-comments-in-a-repository
#
# @example Get the comments for issues in the octokit repository
# @client.issues_comments("octokit/octokit.rb")
#
# @example Get issues comments, sort by updated descending since a time
# @client.issues_comments("octokit/octokit.rb", {
# :sort => 'desc',
# :direction => 'asc',
# :since => '2010-05-04T23:45:02Z'
# })
def issues_comments(repo, options = {})
paginate "#{Repository.path repo}/issues/comments", options
end
# Get all comments attached to an issue
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param number [Integer] Number ID of the issue
# @return [Array] Array of comments that belong to an issue
# @see https://developer.github.com/v3/issues/comments/#list-comments-on-an-issue
# @example Get comments for issue #25 from octokit/octokit.rb
# Octokit.issue_comments("octokit/octokit.rb", "25")
def issue_comments(repo, number, options = {})
paginate "#{Repository.path repo}/issues/#{number}/comments", options
end
# Get a single comment attached to an issue
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param number [Integer] Number ID of the comment
# @return [Sawyer::Resource] The specific comment in question
# @see https://developer.github.com/v3/issues/comments/#get-a-single-comment
# @example Get comment #1194549 from an issue on octokit/octokit.rb
# Octokit.issue_comments("octokit/octokit.rb", 1194549)
def issue_comment(repo, number, options = {})
paginate "#{Repository.path repo}/issues/comments/#{number}", options
end
# Add a comment to an issue
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param number [Integer] Issue number
# @param comment [String] Comment to be added
# @return [Sawyer::Resource] Comment
# @see https://developer.github.com/v3/issues/comments/#create-a-comment
# @example Add the comment "Almost to v1" to Issue #23 on octokit/octokit.rb
# Octokit.add_comment("octokit/octokit.rb", 23, "Almost to v1")
def add_comment(repo, number, comment, options = {})
post "#{Repository.path repo}/issues/#{number}/comments", options.merge({:body => comment})
end
# Update a single comment on an issue
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param number [Integer] Comment number
# @param comment [String] Body of the comment which will replace the existing body.
# @return [Sawyer::Resource] Comment
# @see https://developer.github.com/v3/issues/comments/#edit-a-comment
# @example Update the comment #1194549 with body "I've started this on my 25-issue-comments-v3 fork" on an issue on octokit/octokit.rb
# Octokit.update_comment("octokit/octokit.rb", 1194549, "Almost to v1, added this on my fork")
def update_comment(repo, number, comment, options = {})
patch "#{Repository.path repo}/issues/comments/#{number}", options.merge({:body => comment})
end
# Delete a single comment
#
# @param repo [Integer, String, Repository, Hash] A GitHub repository
# @param number [Integer] Comment number
# @return [Boolean] Success
# @see https://developer.github.com/v3/issues/comments/#delete-a-comment
# @example Delete the comment #1194549 on an issue on octokit/octokit.rb
# Octokit.delete_comment("octokit/octokit.rb", 1194549)
def delete_comment(repo, number, options = {})
boolean_from_response :delete, "#{Repository.path repo}/issues/comments/#{number}", options
end
end
end
end