octopolo 0.3.6 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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