octopolo 0.3.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjBkOWNlNGY5ZGYyYThmNjE4NjA5YzAyNDhmOGViOTVhMmI0ZTJkNw==
4
+ ZTBjNTI0MzM3MzRiZmM4ODYxNGNlM2I4YjFjYjFiODkyZTYxMmNjNg==
5
5
  data.tar.gz: !binary |-
6
- ZGUzMGFmZmM2ZGQxNDk5YjhhNjFlMWY3M2IxOWM3YmRiMWZjMTA2MA==
6
+ MjQ3MDg1YWM2ZTMyNzdiMjlhMzFkM2FlNzg0YmQyM2I5MTQ0OTNjZQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NDcwNjNkYTQ3OWI2OTRjNTE3YWRkMWEyOTRlMTJiZDg0OGRiYWJkMGFhZGZh
10
- NGMxOTM0MjU5ZTAxZGE1NzllNmIyODQ2ODdlYmUwODQzNTU0OTYzZDQwY2Nm
11
- YzQyYWJlNDg5OWM3OTllNjNkZTUwYzUzNjdlYWRiMzdkNjk5YmY=
9
+ ZTUzNWI1NWZkMTBiY2Y3M2MzZTg1MmEyMmIwMGEyZmJkMjg3NmJhZmE4ZmIy
10
+ MTNlNzBkYTJiMDU3NDcwYWQ5MDE1MDQ1NGE3M2NmNDYyNGY4ZGZiNDg5ZjBk
11
+ NGUzYzE4Y2NkY2FlZmU2ZGRhYjU5OTM4MWIwODA2MDBlODRhMDI=
12
12
  data.tar.gz: !binary |-
13
- OThiMTI3NjcyZmVjMDI5OWJlMTZlZTVkMTA1Njk1ODZiZmU4NTk0Zjc5YWRh
14
- OGU2NmM4MmEzOGMzYzQ5Y2RhYThlN2U5Y2Q5Mjk1OGM3MTJmMjFjNzhiZGI3
15
- OTAzYmE5YjVkMWY2MjJlZmU0MTU3MzE5MWE4MzY3MGEyYmU5Zjg=
13
+ NWI5YzI3NWU5NDU2YTIxODVhNzY2OWY5OGY5MTk4M2JkMGU4YTU1OWYwZGU3
14
+ ZDk1MzIwMWZkZGYxNDBmZjhjNTczY2RkNzAwYjQ4NjQ5NTg5NmI4OWI1NThl
15
+ ZjYyNTc2YjAyMDI0MTk2ZGIwZmUwYmRkOWMwODAxMTA4ZTRkYmM=
data/.travis.yml CHANGED
@@ -1,3 +1,7 @@
1
+ sudo: false
2
+ branches:
3
+ only:
4
+ - master
1
5
  language: ruby
2
6
  rvm:
3
7
  - 1.9.3
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,8 @@
1
+ #### v0.4.0
2
+ * Adding issue command to create issues.
3
+
4
+ > Brian Bergstrom: Nick LaMuro: https://github.com/sportngin/octopolo/pull/54
5
+
1
6
  #### v0.3.6
2
7
  * Some git commands are expected to return non-zero
3
8
 
@@ -0,0 +1,14 @@
1
+ desc "Create an issue for the current project."
2
+ command 'issue' do |c|
3
+ config = Octopolo::Config.parse
4
+ user_config = Octopolo::UserConfig.parse
5
+
6
+ c.desc "Use $EDITOR to update PR description before creating"
7
+ c.switch [:e, :editor], :default_value => user_config.editor
8
+
9
+ c.action do |global_options, options, args|
10
+ require_relative '../scripts/issue'
11
+ options = global_options.merge(options)
12
+ Octopolo::Scripts::Issue.execute options
13
+ end
14
+ end
@@ -71,6 +71,14 @@ module Octopolo
71
71
  client.create_pull_request *args
72
72
  end
73
73
 
74
+ def self.issue *args
75
+ client.issue *args
76
+ end
77
+
78
+ def self.create_issue *args
79
+ client.create_issue *args
80
+ end
81
+
74
82
  def self.add_comment *args
75
83
  client.add_comment *args
76
84
  end
@@ -101,12 +109,11 @@ module Octopolo
101
109
  client.remove_label *args
102
110
  end
103
111
 
104
- def self.add_labels_to_pull *args
112
+ def self.add_labels_to_issue *args
105
113
  client.add_labels_to_an_issue *args
106
114
  end
107
115
 
108
116
 
109
-
110
117
  # now that you've set up your credentials, try again
111
118
  TryAgain = Class.new(StandardError)
112
119
  # the credentials you've entered are bad
@@ -0,0 +1,106 @@
1
+ require "octokit"
2
+
3
+ module Octopolo
4
+ module GitHub
5
+ class Issue
6
+ attr_accessor :data
7
+ attr_accessor :repo_name
8
+ attr_accessor :number
9
+
10
+ def initialize repo_name, number, data = nil
11
+ raise MissingParameter if repo_name.nil? or number.nil?
12
+
13
+ self.repo_name = repo_name
14
+ self.number = number
15
+ self.data = data
16
+ end
17
+
18
+ # Public: Create a issue for the given repo
19
+ #
20
+ # repo_name - Full name ("account/repo") of the repo in question
21
+ # options - Hash of issue information
22
+ # title: Title of the issue
23
+ # description: Brief description of the issue
24
+ #
25
+ # Returns a Issue instance
26
+ def self.create(repo_name, options)
27
+ # create via the API
28
+ creator = IssueCreator.perform(repo_name, options)
29
+ # wrap in our class
30
+ new repo_name, creator.number, creator.data
31
+ end
32
+
33
+ def data
34
+ @data ||= GitHub.issue(repo_name, number)
35
+ rescue Octokit::NotFound
36
+ raise NotFound
37
+ end
38
+
39
+ def title
40
+ data.title
41
+ end
42
+
43
+ def url
44
+ data.html_url
45
+ end
46
+
47
+ def commenter_names
48
+ exclude_octopolo_user (comments.map{ |comment| GitHub::User.new(comment.user.login).author_name }.uniq)
49
+ end
50
+
51
+ def exclude_octopolo_user(user_list)
52
+ user_list.reject{|u| GitHub.excluded_users.include?(u) }
53
+ end
54
+
55
+ def body
56
+ data.body || ""
57
+ end
58
+
59
+ def external_urls
60
+ # extract http and https URLs from the body
61
+ URI.extract body, %w(http https)
62
+ end
63
+
64
+ def human_app_name
65
+ repo = repo_name.split("/").last
66
+ repo.split("_").map(&:capitalize).join(" ")
67
+ end
68
+
69
+ def comments
70
+ @comments ||= GitHub.issue_comments(repo_name, number)
71
+ end
72
+
73
+ # Public: Add a comment to the issue
74
+ #
75
+ # message - A String containing the desired comment body
76
+ def write_comment(message)
77
+ GitHub.add_comment repo_name, number, ":octocat: #{message}"
78
+ rescue Octokit::UnprocessableEntity => error
79
+ raise CommentFailed, "Unable to write the comment: '#{error.message}'"
80
+ end
81
+
82
+ # Public: Adds labels to a pull-request
83
+ #
84
+ # labels - label objects, can be a single label, an array of labels,
85
+ # or a list of labels
86
+ def add_labels(*labels)
87
+ built_labels = Label.build_label_array(labels)
88
+ GitHub.add_labels_to_issue(repo_name, number, built_labels.map(&:name) )
89
+ end
90
+
91
+ # Public: Removes labels from a pull-request,
92
+ #
93
+ # labels - label objects, can be a single label, an array of labels,
94
+ # or a list of labels
95
+ def remove_labels(*labels)
96
+ Label.build_label_array(labels).each do |built_label|
97
+ GitHub.remove_label(repo_name, number, built_label.name)
98
+ end
99
+ end
100
+
101
+ MissingParameter = Class.new StandardError
102
+ NotFound = Class.new StandardError
103
+ CommentFailed = Class.new StandardError
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,147 @@
1
+ require_relative "../renderer"
2
+ require 'tempfile'
3
+
4
+ module Octopolo
5
+ module GitHub
6
+ class IssueCreator
7
+ include ConfigWrapper
8
+ # for instantiating the issue creator
9
+ attr_accessor :repo_name
10
+ attr_accessor :options
11
+ # for caputuring the created issue information
12
+ attr_accessor :number
13
+ attr_accessor :data
14
+
15
+ # Public: Create a issue for the given repo with the given options
16
+ #
17
+ # repo_name - Full name ("account/repo") of the repo in question
18
+ # options - Hash of issue information
19
+ # title: Title of the issue
20
+ def initialize repo_name, options
21
+ self.repo_name = repo_name
22
+ self.options = options
23
+ end
24
+
25
+ # Public: Create a issue for the given repo with the given options
26
+ #
27
+ # repo_name - Full name ("account/repo") of the repo in question
28
+ # options - Hash of issue information
29
+ # title: Title of the issue
30
+ #
31
+ # Returns the IssueCreator instance
32
+ def self.perform repo_name, options
33
+ new(repo_name, options).tap do |creator|
34
+ creator.perform
35
+ end
36
+ end
37
+
38
+ # Public: Create the issue
39
+ #
40
+ # Returns an array with the first element being the issue's
41
+ # number, the second being a Mash of the response from GitHub's API
42
+ def perform
43
+ # labels option cannot be null due to https://github.com/octokit/octokit.rb/pull/538
44
+ result = GitHub.create_issue(repo_name, title, body, labels: [])
45
+ # capture the information
46
+ self.number = result.number
47
+ self.data = result
48
+ rescue => e
49
+ raise CannotCreate, e.message
50
+ end
51
+
52
+ # Public: The created resource's details
53
+ def data
54
+ @data || raise(NotYetCreated)
55
+ end
56
+
57
+ # Public: The created issue's number
58
+ def number
59
+ @number || raise(NotYetCreated)
60
+ end
61
+
62
+ # Public: Title of the issue
63
+ #
64
+ # Returns a String with the title
65
+ def title
66
+ options[:title] || raise(MissingAttribute)
67
+ end
68
+
69
+ # Public: The Pivotal Tracker story IDs associated with the issue
70
+ #
71
+ # Returns an Array of Strings
72
+ def pivotal_ids
73
+ options[:pivotal_ids] || []
74
+ end
75
+
76
+ # Public: Jira Issue IDs associated with the issue
77
+ #
78
+ # Returns an Array of Strings
79
+ def jira_ids
80
+ options[:jira_ids] || []
81
+ end
82
+
83
+ # Public: Jira Url associated with the issue
84
+ #
85
+ # Returns Jira Url
86
+ def jira_url
87
+ config.jira_url
88
+ end
89
+
90
+ # Public: Rendering template for body property
91
+ #
92
+ # Returns Name of template file
93
+ def renderer_template
94
+ Renderer::ISSUE_BODY
95
+ end
96
+
97
+ # Public: Temporary file for body editing
98
+ #
99
+ # Returns Name of temporary file
100
+ def body_edit_temp_name
101
+ 'octopolo_issue'
102
+ end
103
+
104
+
105
+ # Public: The body (primary copy) of the issue
106
+ #
107
+ # Returns a String
108
+ def body
109
+ output = Renderer.render renderer_template, body_locals
110
+ output = edit_body(output) if options[:editor]
111
+ output
112
+ end
113
+
114
+ def edit_body(body)
115
+ return body unless ENV['EDITOR']
116
+
117
+ # Open the file, write the contents, and close it
118
+ tempfile = Tempfile.new([body_edit_temp_name, '.md'])
119
+ tempfile.write(body)
120
+ tempfile.close
121
+
122
+ # Allow the user to edit the file
123
+ system "#{ENV['EDITOR']} #{tempfile.path}"
124
+
125
+ # Reopen the file, read the contents, and delete it
126
+ tempfile.open
127
+ output = tempfile.read
128
+ tempfile.unlink
129
+
130
+ output
131
+ end
132
+
133
+ # Public: The local variables to pass into the template
134
+ def body_locals
135
+ {
136
+ pivotal_ids: pivotal_ids,
137
+ jira_ids: jira_ids,
138
+ jira_url: jira_url,
139
+ }
140
+ end
141
+
142
+ MissingAttribute = Class.new(StandardError)
143
+ NotYetCreated = Class.new(StandardError)
144
+ CannotCreate = Class.new(StandardError)
145
+ end
146
+ end
147
+ end
@@ -1,20 +1,10 @@
1
+ require_relative "issue"
1
2
  require_relative "../week"
2
3
  require "octokit"
3
4
 
4
5
  module Octopolo
5
6
  module GitHub
6
- class PullRequest
7
- attr_accessor :pull_request_data
8
- attr_accessor :repo_name
9
- attr_accessor :number
10
-
11
- def initialize repo_name, number, pull_request_data = nil
12
- raise MissingParameter if repo_name.nil? or number.nil?
13
-
14
- self.repo_name = repo_name
15
- self.number = number
16
- self.pull_request_data = pull_request_data
17
- end
7
+ class PullRequest < Issue
18
8
 
19
9
  # Public: All closed pull requests for a given repo
20
10
  #
@@ -42,100 +32,39 @@ module Octopolo
42
32
  # create via the API
43
33
  creator = PullRequestCreator.perform(repo_name, options)
44
34
  # wrap in our class
45
- new repo_name, creator.number, creator.pull_request_data
35
+ new repo_name, creator.number, creator.data
46
36
  end
47
37
 
48
- def pull_request_data
49
- @pull_request_data ||= GitHub.pull_request(repo_name, number)
38
+ def data
39
+ @data ||= GitHub.pull_request(repo_name, number)
50
40
  rescue Octokit::NotFound
51
41
  raise NotFound
52
42
  end
53
43
 
54
- def title
55
- pull_request_data.title
56
- end
57
-
58
- def url
59
- pull_request_data.html_url
60
- end
61
-
62
44
  def branch
63
- pull_request_data.head.ref
45
+ data.head.ref
64
46
  end
65
47
 
66
48
  def mergeable?
67
- pull_request_data.mergeable
49
+ data.mergeable
68
50
  end
69
51
 
70
52
  def week
71
- Week.parse pull_request_data.closed_at
53
+ Week.parse data.closed_at
72
54
  end
73
55
 
74
56
  def commenter_names
75
- exlude_octopolo_user (comments.map{ |comment| GitHub::User.new(comment.user.login).author_name }.uniq - author_names)
57
+ exclude_octopolo_user (comments.map{ |comment| GitHub::User.new(comment.user.login).author_name }.uniq - author_names)
76
58
  end
77
59
 
78
60
  def author_names
79
- exlude_octopolo_user commits.map(&:author_name).uniq
80
- end
81
-
82
- def exlude_octopolo_user(user_list)
83
- user_list.reject{|u| GitHub.excluded_users.include?(u) }
84
- end
85
-
86
- def body
87
- pull_request_data.body || ""
88
- end
89
-
90
- def external_urls
91
- # extract http and https URLs from the body
92
- URI.extract body, %w(http https)
93
- end
94
-
95
- def human_app_name
96
- repo = repo_name.split("/").last
97
- repo.split("_").map(&:capitalize).join(" ")
61
+ exclude_octopolo_user commits.map(&:author_name).uniq
98
62
  end
99
63
 
100
64
  def commits
101
65
  @commits ||= Commit.for_pull_request self
102
66
  end
103
67
 
104
- def comments
105
- @comments ||= GitHub.issue_comments(repo_name, number)
106
- end
107
-
108
- # Public: Add a comment to the pull request
109
- #
110
- # message - A String containing the desired comment body
111
- def write_comment(message)
112
- GitHub.add_comment repo_name, number, ":octocat: #{message}"
113
- rescue Octokit::UnprocessableEntity => error
114
- raise CommentFailed, "Unable to write the comment: '#{error.message}'"
115
- end
116
-
117
- # Public: Adds labels to a pull-request
118
- #
119
- # labels - label objects, can be a single label, an array of labels,
120
- # or a list of labels
121
- def add_labels(*labels)
122
- built_labels = Label.build_label_array(labels)
123
- GitHub.add_labels_to_pull(repo_name, number, built_labels.map(&:name) )
124
- end
125
-
126
- # Public: Removes labels from a pull-request,
127
- #
128
- # labels - label objects, can be a single label, an array of labels,
129
- # or a list of labels
130
- def remove_labels(*labels)
131
- Label.build_label_array(labels).each do |built_label|
132
- GitHub.remove_label(repo_name, number, built_label.name)
133
- end
134
- end
135
-
136
- MissingParameter = Class.new StandardError
137
- NotFound = Class.new StandardError
138
- CommentFailed = Class.new StandardError
139
68
  end
140
69
  end
141
70
  end