robopigeon 0.3.0 → 0.3.1

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,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25d50f00dc30aa78bd9389cee8da7d93aa04920e4db5c10433f39c2df4d97b0f
4
- data.tar.gz: c0f86cfe9dc63bb753d4ee5e88cfe16512fce547fcdb649ffe4776282c3162dd
3
+ metadata.gz: e79ffa789106a62a231ad2f47d77a0a4f40d6f10f402a5d850854a8d6fc28e6b
4
+ data.tar.gz: 68cf7d61408fae7074e0866a0ed8617206d6298d89d0efd840576dd436eed43c
5
5
  SHA512:
6
- metadata.gz: 9f980108a24e6e081f073e9747efca1fcb4cb14f776aa911cb4a60c769529401abf140b0f09de6c68208f1d78dde56a6ea8f8ae899b8ab3d943676be34bf8a80
7
- data.tar.gz: 94b3b6a2f9631eb610ddfb2bf13fc8f885d3962d65a5dbdcfeb7c56ad44bbdf25d298db7fdf7b08ad9b3cd463cabc65a9c88c3310fd7a0b3a21960be94af7e0e
6
+ metadata.gz: 71ed0f3218d805e49954f88257b29a218c5c1e28983e57e403e8c8576c375074b732eda9b548b8aa408be2fc22b25a9c3fcce9bc46491782d631c9707eb15f28
7
+ data.tar.gz: e1721290eba3a076d1801c4ef14d3806e48a932d7fd7cd0d89dc2317b0cefc5e9adcb2155199d6ae0129678f6be9bc4c286b2e1301d1bcbc170eb828cd34a8cd
data/.version CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.3.1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## 0.3.1 (2019-04-8)
2
+
3
+ ### Added
4
+
5
+ - Allow slack user methods to take an email and name
6
+ - Add helper for code change stats since deployment
7
+
8
+ ### Fixed
9
+
10
+ - Show line numbers and file name in robopigeon.rb correctly
11
+ - Helpers are included even if defined after the main gem
12
+ - All dsls should extend base
13
+ - Fix jira ticket slack formatter issue
14
+ - Remove trailing slash from some lookups that Jira seems to dislike
15
+
1
16
  ## 0.3.0 (2019-04-8)
2
17
 
3
18
  ### Added
data/exe/robopigeon CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'robopigeon'
4
4
 
5
+ Bundler.require if defined?(Bundler)
6
+
5
7
  def usage(bot)
6
8
  bot.usage
7
9
  exit 1
@@ -15,9 +15,8 @@ module RoboPigeon::Dsl
15
15
  init_help
16
16
  init_new
17
17
  if File.exist?(file)
18
- instance_exec do
19
- eval(File.read(file))
20
- end
18
+ contents = File.read(file)
19
+ instance_eval(contents, file)
21
20
  else
22
21
  init_job
23
22
  end
@@ -3,6 +3,19 @@ module RoboPigeon::Dsl
3
3
  # extensions. That's very helpful if you're trying to write an
4
4
  # extension that interfaces with another extension or built in.
5
5
  class Base < RoboPigeon::Dsl::Job
6
- include RoboPigeon::Dsl::Helpers
6
+ def respond_to_missing?(method, include_private)
7
+ RoboPigeon::Dsl::Helpers.instance_methods(include_private).include?(method)
8
+ end
9
+
10
+ def method_missing(method, *args)
11
+ self.class.class_exec do
12
+ include RoboPigeon::Dsl::Helpers
13
+ end
14
+ if respond_to?(method)
15
+ send(method, *args)
16
+ else
17
+ super
18
+ end
19
+ end
7
20
  end
8
21
  end
@@ -28,6 +28,7 @@ module RoboPigeon::Dsl
28
28
  end
29
29
 
30
30
  def job(*args, &block)
31
+ initial_name = args.shift
31
32
  this_job = {
32
33
  desc: args.pop,
33
34
  action: proc do
@@ -35,7 +36,7 @@ module RoboPigeon::Dsl
35
36
  job.instance_eval(&block)
36
37
  end
37
38
  }
38
- jobs[args.shift] = this_job
39
+ jobs[initial_name] = this_job
39
40
  args.each do |arg|
40
41
  jobs[arg] = this_job.merge(hidden: true)
41
42
  end
@@ -20,7 +20,7 @@ module RoboPigeon::GitLab
20
20
  page: page
21
21
  )
22
22
  deployment = deployments.select { |dep| dep.environment.name == environment }.first
23
- return get_deployment(environment, project, page + 1) if deployment.nil? && deployments.has_next_page?
23
+ return get_deployment(environment, page + 1) if deployment.nil? && deployments.has_next_page?
24
24
 
25
25
  deployment
26
26
  end
@@ -1,6 +1,6 @@
1
1
  require 'gitlab'
2
2
  module RoboPigeon::Dsl
3
- class GitLabCommit
3
+ class GitLabCommit < RoboPigeon::Dsl::Base
4
4
  attr_accessor :commit
5
5
  def initialize
6
6
  self.commit = RoboPigeon::GitLab::Commit.new
@@ -24,7 +24,7 @@ module RoboPigeon::Dsl
24
24
  RoboPigeon::Documentarian.add_command('deployment_shortlog', block: ['helpers'], params: [{ name: 'environment', type: 'String', desc: 'the name of a gitlab operations environment', example: 'production' }], desc: 'get a shortlog of changes between head and the specified environment')
25
25
  def deployment_shortlog(environment)
26
26
  dep = RoboPigeon::GitLab::Client.get_deployment(environment)
27
- `git shortlog --no-merges #{dep.sha}..`
27
+ `git shortlog --no-merges #{dep.sha}..`.strip
28
28
  end
29
29
 
30
30
  RoboPigeon::Documentarian.add_command('deployment_time', block: ['helpers'], params: [{ name: 'environment', type: 'String', desc: 'the name of a gitlab operations environment', example: 'production' }], desc: 'get the time the last deployment for the given environment happened')
@@ -39,6 +39,12 @@ module RoboPigeon::Dsl
39
39
  "#{ENV['CI_PROJECT_URL']}/environments/#{dep.environment.id}"
40
40
  end
41
41
 
42
+ RoboPigeon::Documentarian.add_command('deployment_code_change_stats', block: ['helpers'], params: [{ name: 'environment', type: 'String', desc: 'the name of a gitlab operations environment', example: 'production' }], desc: 'Get code change stats since the latest deployment')
43
+ def deployment_code_change_stats(environment)
44
+ dep = RoboPigeon::GitLab::Client.get_deployment(environment)
45
+ `git diff --shortstat #{dep.sha}`.strip
46
+ end
47
+
42
48
  RoboPigeon::Documentarian.add_command(
43
49
  'deployment_git_log_jira_tickets',
44
50
  block: ['helpers'],
@@ -1,5 +1,5 @@
1
1
  module RoboPigeon::Dsl
2
- class JenkinsRoot
2
+ class JenkinsRoot < RoboPigeon::Dsl::Base
3
3
  def self.run(&block)
4
4
  instance = new
5
5
  instance.instance_eval(&block)
@@ -53,7 +53,7 @@ module RoboPigeon::Dsl
53
53
  RoboPigeon::Jenkins::Client.token = token
54
54
  end
55
55
  end
56
- class Jenkins
56
+ class Jenkins < JenkinsRoot
57
57
  attr_accessor :job
58
58
  def initialize
59
59
  self.job = RoboPigeon::Jenkins::Job.new
@@ -17,7 +17,7 @@ module RoboPigeon::Dsl
17
17
  def jira_last_created_ticket_slack_link
18
18
  issue_id = RoboPigeon::Jira::Client.last_created_ticket
19
19
  jira_url = RoboPigeon::Jira::Client.api_url
20
- "<#{issue_id}|#{jira_url}/browse/#{issue_id}>"
20
+ "<#{jira_url}/browse/#{issue_id}|#{issue_id}>"
21
21
  end
22
22
 
23
23
  RoboPigeon::Documentarian.add_command(
@@ -5,19 +5,19 @@ module RoboPigeon::Jira
5
5
  MAX_TRANSITIONS = 10
6
6
  ISSUE_PATH = '/rest/api/2/issue'.freeze
7
7
  attr_accessor :ticket, :project, :issue_type, :summary, :fields,
8
- :assignee, :reporter, :description
8
+ :assignee, :duedate, :reporter, :description
9
9
 
10
10
  def initialize(ticket = nil)
11
11
  self.ticket = ticket
12
12
  self.fields = {}
13
- update_from_server
13
+ attempt_update_from_server
14
14
  self.project = ticket.split('-')[0] if ticket
15
15
  end
16
16
 
17
- def update_from_server
17
+ def attempt_update_from_server
18
18
  return unless ticket
19
19
 
20
- get = jira_request.get("#{ISSUE_PATH}/#{ticket}/")
20
+ get = jira_request.get("#{ISSUE_PATH}/#{ticket}")
21
21
  raise "Failed to look up issue #{ticket}" unless get.status < 400
22
22
 
23
23
  raw = JSON.parse(get.body)
@@ -40,6 +40,7 @@ module RoboPigeon::Jira
40
40
  project: { key: project },
41
41
  issuetype: { name: issue_type },
42
42
  summary: summary,
43
+ duedate: duedate,
43
44
  description: description,
44
45
  assignee: { name: reporter }
45
46
  }.merge(fields)
@@ -97,13 +98,15 @@ module RoboPigeon::Jira
97
98
 
98
99
  self.fields[field] = if fields[field]['allowedValues'].nil?
99
100
  value
101
+ elsif fields[field]['schema']['type'] == 'array'
102
+ [{ name: value }]
100
103
  else
101
104
  { value: value }
102
105
  end
103
106
 
104
107
  if ticket
105
108
  post = jira_request.put do |req|
106
- req.url "#{ISSUE_PATH}/#{ticket}/"
109
+ req.url "#{ISSUE_PATH}/#{ticket}"
107
110
  req.body = { fields: self.fields }.to_json
108
111
  end
109
112
  end
@@ -124,7 +127,7 @@ module RoboPigeon::Jira
124
127
 
125
128
  def perform_transition(transition)
126
129
  require_ticket
127
- get_fields = jira_request.get("#{ISSUE_PATH}/#{ticket}/transitions?expand=transitions.fields")
130
+ get_fields = jira_request.get("#{ISSUE_PATH}/#{ticket}?expand=transitions.fields")
128
131
  transition_details = JSON.parse(get_fields.body)['transitions'].find do |trans|
129
132
  trans['name'].casecmp(transition).zero?
130
133
  end
@@ -139,7 +142,7 @@ module RoboPigeon::Jira
139
142
  def current_state
140
143
  require_ticket
141
144
  get = jira_request.get do |req|
142
- req.url "#{ISSUE_PATH}/#{ticket}/"
145
+ req.url "#{ISSUE_PATH}/#{ticket}"
143
146
  end
144
147
  JSON.parse(get.body)['fields']['status']['name']
145
148
  end
@@ -1,5 +1,5 @@
1
1
  module RoboPigeon::Dsl
2
- class JiraTicket
2
+ class JiraTicket < RoboPigeon::Dsl::Base
3
3
  include RoboPigeon::Dsl::Helpers
4
4
  attr_accessor :ticket
5
5
 
@@ -110,7 +110,7 @@ module RoboPigeon::Dsl
110
110
  'field',
111
111
  block: %w[job jira ticket],
112
112
  params: [
113
- { name: 'field_name', type: 'String', desc: 'the name of the field you want to set', example: 'duedate' },
113
+ { name: 'field_name', type: 'String', desc: 'the name of the field you want to set', example: 'Regression Test Release Date' },
114
114
  { name: 'field_value', type: 'String', desc: 'what to set that field to', example: '2/10/2030' }
115
115
  ],
116
116
  desc: 'set or update a field to a value'
@@ -1,6 +1,5 @@
1
1
  module RoboPigeon::Dsl
2
- class SlackAttachment
3
- include RoboPigeon::Dsl::Helpers
2
+ class SlackAttachment < RoboPigeon::Dsl::Base
4
3
  attr_accessor :attachment
5
4
 
6
5
  def initialize
@@ -28,15 +28,18 @@ module RoboPigeon::Slack
28
28
  end
29
29
 
30
30
  def get_user(search)
31
+ lookup = search.shift
31
32
  begin
32
- users = client.users_search(user: search.downcase).try(:members)
33
+ users = client.users_search(user: lookup.downcase).try(:members) unless lookup.nil?
33
34
  rescue ::Faraday::Error => e
34
35
  puts "Giving up on slack user lookup because the slack client raised a #{e.class}:\n#{e.message}"
35
36
  users = nil
36
37
  end
37
38
 
38
39
  if users.nil? || users.empty? || users.length != 1
39
- nil
40
+ return nil if search.empty?
41
+
42
+ get_user(search)
40
43
  else
41
44
  users.try(:first)
42
45
  end
@@ -46,7 +46,7 @@ module RoboPigeon::Dsl
46
46
  end
47
47
 
48
48
  RoboPigeon::Documentarian.add_command('user', block: %w[job slack], params: [{ name: 'search', type: 'String', desc: 'the name, email, or slack handle of a user to search for', example: 'robopigeon@ives.dev' }], desc: 'add a single user recipient to your message, can be used multiple times')
49
- def user(user)
49
+ def user(*user)
50
50
  message.users.push(RoboPigeon::Slack::Client.get_user(user).try(:id))
51
51
  end
52
52
 
@@ -2,7 +2,7 @@ module RoboPigeon::Dsl
2
2
  module Helpers
3
3
  module Slack
4
4
  RoboPigeon::Documentarian.add_command('slack_user_for', block: ['helpers'], params: [{ name: 'search', type: 'String', desc: 'the name, email, or slack handle of a user to search for', example: 'robopigeon@ives.dev' }], desc: 'Searches for a given user and returns a formatted slack message mention')
5
- def slack_user_for(search)
5
+ def slack_user_for(*search)
6
6
  uid = RoboPigeon::Slack::Client.get_user(search).try(:id)
7
7
  return '' if uid.nil?
8
8
 
@@ -10,11 +10,12 @@ module RoboPigeon::Dsl
10
10
  end
11
11
 
12
12
  RoboPigeon::Documentarian.add_command('slack_name_for', block: ['helpers'], params: [{ name: 'search', type: 'String', desc: 'the name, email, or slack handle of a user to search for', example: 'robopigeon@ives.dev' }], desc: 'Searches for a given user and returns their slack handle with an @')
13
- def slack_name_for(search)
14
- name = RoboPigeon::Slack::Client.get_user(search).try(:name)
13
+ def slack_name_for(*search)
14
+ uid = RoboPigeon::Slack::Client.get_user(search).try(:name)
15
+
15
16
  return '' if uid.nil?
16
17
 
17
- "@#{name}"
18
+ "@#{uid}"
18
19
  end
19
20
 
20
21
  RoboPigeon::Documentarian.add_command('slack_user_group', block: ['helpers'], params: [{ name: 'id', type: 'String', desc: 'the usergroup id to mention', example: 'robopigeon@ives.dev' }], desc: 'a message formatted mention of the given slack group id')
@@ -24,10 +24,10 @@ module RoboPigeon::Slack
24
24
  end
25
25
 
26
26
  def send!
27
- users.each do |user|
27
+ users.reject(&:nil?).each do |user|
28
28
  send_message(user)
29
29
  end
30
- channels.each do |channel|
30
+ channels.reject(&:nil?).each do |channel|
31
31
  send_message(channel)
32
32
  end
33
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: robopigeon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Ives
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-08 00:00:00.000000000 Z
11
+ date: 2019-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gitlab