lita-github 0.0.13 → 0.0.14
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 +4 -4
- data/lib/lita-github.rb +1 -0
- data/lib/lita-github/general.rb +23 -17
- data/lib/lita-github/r.rb +2 -6
- data/lib/lita-github/version.rb +2 -2
- data/lib/lita/handlers/github.rb +6 -3
- data/lib/lita/handlers/github_issues.rb +110 -0
- data/lib/lita/handlers/github_org.rb +132 -1
- data/lib/lita/handlers/github_pr.rb +1 -1
- data/locales/en.yml +26 -2
- data/spec/unit/lita-github/general_spec.rb +27 -12
- data/spec/unit/lita-github/r_spec.rb +0 -44
- data/spec/unit/lita-github/version_spec.rb +7 -7
- data/spec/unit/lita/handlers/github_issues_spec.rb +162 -0
- data/spec/unit/lita/handlers/github_org_spec.rb +259 -2
- data/spec/unit/lita/handlers/github_pr_spec.rb +63 -49
- data/spec/unit/lita/handlers/github_repo_spec.rb +1 -1
- data/spec/unit/lita/handlers/github_spec.rb +20 -8
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2012ebdeed7b0904f7d65cb1d1da4fe0988a031b
|
4
|
+
data.tar.gz: f8f82d62bd1e38ab05156f65b8ec159ae265b98b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c74417471b025d45253f622a97e054e1cfa49a0fabbf55879c9b14b45d9293b414407e62c1d357d40a16a66817616831143d725665e9a720ba8472775d8dae5
|
7
|
+
data.tar.gz: bfba8e8cb4ea94d8b6164c5489bcb3d4624be502f28b2a8a1a357ce6289f7b3559da6567647685ac6b592dec74d1a73d505cb4002b1313716a3100e27f78afe3
|
data/lib/lita-github.rb
CHANGED
data/lib/lita-github/general.rb
CHANGED
@@ -21,31 +21,37 @@ module LitaGithub
|
|
21
21
|
#
|
22
22
|
# @author Tim Heckman <tim@pagerduty.com>
|
23
23
|
module General
|
24
|
-
#
|
24
|
+
# Convert the value of parameter 1 to an Integer if it looks like it should be one
|
25
25
|
#
|
26
26
|
# @author Tim Heckman <tim@pagerduty.com>
|
27
|
-
# @param
|
28
|
-
# @return [
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
k, v = opt.strip.split(':')
|
33
|
-
k = k.to_sym
|
34
|
-
o[k] = v unless o.key?(k)
|
35
|
-
end
|
36
|
-
o
|
27
|
+
# @param value [String] the value to see if it should be an Integer
|
28
|
+
# @return [Integer] if the String <tt>value</tt> looks like an Integer (<tt>/^\d+$/</tt>), return it as one
|
29
|
+
# @return [String] if the String <tt>value</tt> is not an Integer, return as is
|
30
|
+
def to_i_if_numeric(value)
|
31
|
+
/^\d+$/.match(value) ? value.to_i : value
|
37
32
|
end
|
38
33
|
|
39
|
-
#
|
34
|
+
# For use when parsing options using <tt>opt_parse()</tt>, this method converts the key to a downcased symbol
|
35
|
+
# for use within the option Hash.
|
36
|
+
#
|
37
|
+
# @author Tim Heckman <tim@pagerduty.com>
|
38
|
+
# @param k [String] the key
|
39
|
+
# @param v [Any] the value
|
40
|
+
# @return [Array] the first element is <tt>key</tt> as a downcased symbol, the second is <tt>v</tt> with no changes
|
41
|
+
def symbolize_opt_key(k, v)
|
42
|
+
[k.downcase.to_sym, v]
|
43
|
+
end
|
44
|
+
|
45
|
+
# Parse the options in the command using the option regex
|
40
46
|
#
|
41
47
|
# @author Tim Heckman <tim@pagerduty.com>
|
42
48
|
# @param cmd [String] the full command line provided to Lita
|
43
49
|
# @return [Hash] the key:value pairs that were in the command string
|
44
|
-
def
|
50
|
+
def opts_parse(cmd)
|
45
51
|
o = {}
|
46
|
-
cmd.scan(LitaGithub::R::
|
47
|
-
k, v = opt.strip.split(':')
|
48
|
-
|
52
|
+
cmd.scan(LitaGithub::R::OPT_REGEX).flatten.each do |opt|
|
53
|
+
k, v = symbolize_opt_key(*opt.strip.split(':'))
|
54
|
+
next if o.key?(k)
|
49
55
|
|
50
56
|
# if it looks like we're using the extended option (first character is a " or '):
|
51
57
|
# slice off the first and last character of the string
|
@@ -53,7 +59,7 @@ module LitaGithub
|
|
53
59
|
# do nothing
|
54
60
|
v = v.slice!(1, (v.length - 2)) if %w(' ").include?(v.slice(0))
|
55
61
|
|
56
|
-
o[k] = v
|
62
|
+
o[k] = to_i_if_numeric(v)
|
57
63
|
end
|
58
64
|
o
|
59
65
|
end
|
data/lib/lita-github/r.rb
CHANGED
@@ -22,13 +22,9 @@ module LitaGithub
|
|
22
22
|
# command alias regex (!gh or !github for example)
|
23
23
|
A_REG ||= '(?:gh|github)\s+?'
|
24
24
|
|
25
|
-
# option regex, letting you scan the
|
26
|
-
# key1:value key2:value, etc.
|
27
|
-
OPT_REGEX ||= /((?:\s+?[a-zA-Z0-9_]+?):(?:[a-zA-Z0-9_]+))/
|
28
|
-
|
29
|
-
# extended option regex, letting you scan the string for things like:
|
25
|
+
# option regex, letting you scan the string for things like:
|
30
26
|
# key1:value key2:"value2" key3:'a better value'
|
31
|
-
|
27
|
+
OPT_REGEX ||= /((?:\s+?[a-zA-Z0-9_]+?):(?:(?:".+?")|(?:'.+?')|(?:[a-zA-Z0-9_]+)))/
|
32
28
|
|
33
29
|
# regex matcher for: Org/repo
|
34
30
|
REPO_REGEX = '(?:(?<org>[a-zA-Z0-9_\-]+)(?:\s+?)?\/)?(?:\s+?)?(?<repo>[a-zA-Z0-9_\-]+)'
|
data/lib/lita-github/version.rb
CHANGED
@@ -21,8 +21,8 @@
|
|
21
21
|
# @author Tim Heckman <tim@pagerduty.com>
|
22
22
|
module LitaGithub
|
23
23
|
# lita-github version
|
24
|
-
VERSION = '0.0.
|
24
|
+
VERSION = '0.0.14'
|
25
25
|
|
26
26
|
# lita-github version split amongst different revisions
|
27
|
-
|
27
|
+
MAJOR_VERSION, MINOR_VERSION, REVISION = VERSION.split('.').map(&:to_i)
|
28
28
|
end
|
data/lib/lita/handlers/github.rb
CHANGED
@@ -68,8 +68,9 @@ module Lita
|
|
68
68
|
def self.default_config(config)
|
69
69
|
# when setting default configuration values please remember one thing:
|
70
70
|
# secure and safe by default
|
71
|
-
config.default_team_slug
|
72
|
-
config.repo_private_default
|
71
|
+
config.default_team_slug = nil
|
72
|
+
config.repo_private_default = true
|
73
|
+
config.org_team_add_allowed_perms = %w(pull)
|
73
74
|
|
74
75
|
####
|
75
76
|
# Method Filters
|
@@ -92,7 +93,9 @@ module Lita
|
|
92
93
|
# Lita::Handlers::GithubOrg
|
93
94
|
config.org_team_add_enabled = false
|
94
95
|
config.org_team_rm_enabled = false
|
95
|
-
config.
|
96
|
+
config.org_user_add_enabled = false
|
97
|
+
config.org_user_rm_enabled = false
|
98
|
+
config.org_eject_user_enabled = false
|
96
99
|
end
|
97
100
|
|
98
101
|
def status(response)
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
#
|
3
|
+
# Copyright 2014 PagerDuty, Inc.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require 'lita-github/r'
|
18
|
+
require 'lita-github/general'
|
19
|
+
require 'lita-github/config'
|
20
|
+
require 'lita-github/octo'
|
21
|
+
require 'lita-github/org'
|
22
|
+
require 'lita-github/repo'
|
23
|
+
require 'lita-github/filters'
|
24
|
+
|
25
|
+
module Lita
|
26
|
+
# Lita Handler
|
27
|
+
module Handlers
|
28
|
+
# GitHub Issues Lita Handler
|
29
|
+
class GithubIssues < Handler
|
30
|
+
include LitaGithub::General # Github handler common-use methods
|
31
|
+
include LitaGithub::Config # Github handler Lita configuration methods
|
32
|
+
include LitaGithub::Octo # Github handler common-use Octokit methods
|
33
|
+
include LitaGithub::Org # Github handler common-use Organization methods
|
34
|
+
include LitaGithub::Repo # Github handler common-use Repository methods
|
35
|
+
include LitaGithub::Filters # Github handler common-use method filters
|
36
|
+
|
37
|
+
on :loaded, :setup_octo # from LitaGithub::Octo
|
38
|
+
|
39
|
+
# issue states
|
40
|
+
LI_STATES = %w(open closed all)
|
41
|
+
# issue states
|
42
|
+
LI_SM = %w(created updated comments)
|
43
|
+
# sort direction
|
44
|
+
LI_DIR = %w(asc desc)
|
45
|
+
|
46
|
+
route(
|
47
|
+
/#{LitaGithub::R::A_REG}(?:issues|repo\s+?issues)\s+?#{LitaGithub::R::REPO_REGEX}/,
|
48
|
+
:issues_list,
|
49
|
+
command: true,
|
50
|
+
help: {
|
51
|
+
'gh issues PagerDuty/lita-github' => 'list the issues on a repo',
|
52
|
+
'gh issues PagerDuty/lita-github state:closed sort:updated sort:desc' => 'just showing some option usage'
|
53
|
+
}
|
54
|
+
)
|
55
|
+
|
56
|
+
# This is the handler for listing issues on a repository
|
57
|
+
# @author Tim Heckman <tim@pagerduty.com>
|
58
|
+
def issues_list(response)
|
59
|
+
full_name = rpo(*repo_match(response.match_data))
|
60
|
+
opts = opts_parse(response.message.body)
|
61
|
+
|
62
|
+
oops = validate_list_opts(opts)
|
63
|
+
|
64
|
+
return response.reply(oops) unless oops.empty?
|
65
|
+
|
66
|
+
return response.reply(t('repo_not_found', repo: full_name)) unless repo?(full_name)
|
67
|
+
|
68
|
+
# get the issues that are not pull requests
|
69
|
+
begin
|
70
|
+
issues = octo.list_issues(full_name, opts).reject { |i| i.key?(:pull_request) }
|
71
|
+
rescue Octokit::UnprocessableEntity => e
|
72
|
+
return response.reply(t('issues_list.invalid_opts', m: e.message))
|
73
|
+
rescue StandardError => e
|
74
|
+
return response.reply(t('boom', m: e.message))
|
75
|
+
end
|
76
|
+
|
77
|
+
if issues.empty?
|
78
|
+
reply = t('issues_list.none', r: full_name)
|
79
|
+
else
|
80
|
+
reply = t('issues_list.header', n: issues.length, r: full_name)
|
81
|
+
issues.each { |i| reply << t('issues_list.item', i.to_h.merge(u: i[:user][:login], r: full_name)) }
|
82
|
+
end
|
83
|
+
|
84
|
+
response.reply(reply)
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
90
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
91
|
+
#
|
92
|
+
# Validate the command options
|
93
|
+
#
|
94
|
+
# @param opts [Hash] the key:value pairs from the command
|
95
|
+
# @return [String] the response to reply with if there was a validation failure
|
96
|
+
def validate_list_opts(opts)
|
97
|
+
resp = ''
|
98
|
+
resp << t('issues_list.val_states') if opts.key?(:state) && !LI_STATES.include?(opts[:state])
|
99
|
+
resp << t('issues_list.val_sort') if opts.key?(:sort) && !LI_SM.include?(opts[:sort])
|
100
|
+
resp << t('issues_list.val_direction') if opts.key?(:direction) && !LI_DIR.include?(opts[:direction])
|
101
|
+
resp = "Invalid option(s):\n#{resp}" unless resp.empty?
|
102
|
+
resp
|
103
|
+
end
|
104
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
105
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
106
|
+
end
|
107
|
+
|
108
|
+
Lita.register_handler(GithubIssues)
|
109
|
+
end
|
110
|
+
end
|
@@ -68,6 +68,42 @@ module Lita
|
|
68
68
|
}
|
69
69
|
)
|
70
70
|
|
71
|
+
# rubocop:disable Metrics/LineLength
|
72
|
+
route(
|
73
|
+
/#{LitaGithub::R::A_REG}org\s+?user\s+?add(?<org>\s+?[a-zA-Z0-9_\-]+)?(?<team>\s?[a-zA-Z0-9_\-]+)\s+?(?<username>[a-zA-Z0-9_\-]+)/,
|
74
|
+
:org_user_add,
|
75
|
+
command: true,
|
76
|
+
# confirmation: { allow_self: false },
|
77
|
+
help: {
|
78
|
+
'gh org user add PagerDuty everyone theckman' => 'add the user theckman to the PagerDuty/everyone team -- this requires confirmation from another user. NOTE: This will add the member to the organization if they are not already!!',
|
79
|
+
'gh org user add PagerDuty 42 theckman' => "same as above, except with the team's ID instead of the slug"
|
80
|
+
}
|
81
|
+
)
|
82
|
+
|
83
|
+
route(
|
84
|
+
/#{LitaGithub::R::A_REG}org\s+?user\s+?rm(?<org>\s+?[a-zA-Z0-9_\-]+)?(?<team>\s?[a-zA-Z0-9_\-]+)\s+?(?<username>[a-zA-Z0-9_\-]+)/,
|
85
|
+
:org_user_rm,
|
86
|
+
comamnd: true,
|
87
|
+
# confirmation: { allow_self: false },
|
88
|
+
help: {
|
89
|
+
'gh org team rm PagerDuty everyone theckman' => 'remove the user theckman from the PagerDuty/everyone team, if this is their last team will remove them from the org. Requires confirmation from another user.',
|
90
|
+
'gh org team rm PagerDuty 42 theckman' => "same as above, except with the team's ID instead of the slug"
|
91
|
+
}
|
92
|
+
)
|
93
|
+
# rubocop:enable Metrics/LineLength
|
94
|
+
|
95
|
+
route(
|
96
|
+
/#{LitaGithub::R::A_REG}org\s+?eject(?<org>\s+?[a-zA-Z0-9_\-]+)?(?<username>\s+?[a-zA-Z0-9_\-]+)/,
|
97
|
+
:org_eject_user,
|
98
|
+
command: true,
|
99
|
+
# confirmation: { allow_self: false },
|
100
|
+
help: {
|
101
|
+
'gh org eject PagerDuty theckman' => 'forcibly removes the user from all groups in the organization -- ' \
|
102
|
+
'this is meant for someone leaving the organization. Requires ' \
|
103
|
+
'confirmation from another user.'
|
104
|
+
}
|
105
|
+
)
|
106
|
+
|
71
107
|
def org_teams_list(response)
|
72
108
|
md = response.match_data
|
73
109
|
org = md[:org].nil? ? config.default_org : organization(md[:org].strip)
|
@@ -93,7 +129,7 @@ module Lita
|
|
93
129
|
def org_team_add(response)
|
94
130
|
return response.reply(t('method_disabled')) if func_disabled?(__method__)
|
95
131
|
|
96
|
-
opts =
|
132
|
+
opts = opts_parse(response.message.body)
|
97
133
|
vo = validate_team_add_opts(opts)
|
98
134
|
return response.reply(vo[:msg]) unless vo[:success]
|
99
135
|
|
@@ -131,6 +167,101 @@ module Lita
|
|
131
167
|
end
|
132
168
|
end
|
133
169
|
|
170
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
171
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
172
|
+
def org_user_add(response)
|
173
|
+
return response.reply(t('method_disabled')) if func_disabled?(__method__)
|
174
|
+
|
175
|
+
md = response.match_data
|
176
|
+
org, team, username = [organization(md['org'].strip), md['team'].strip, md['username']]
|
177
|
+
|
178
|
+
begin
|
179
|
+
user_id = octo.user(username)[:id]
|
180
|
+
rescue Octokit::NotFound
|
181
|
+
return response.reply(t('user_not_found', n: username))
|
182
|
+
end
|
183
|
+
|
184
|
+
return response.reply(t('nope')) if octo.user[:id] == user_id
|
185
|
+
|
186
|
+
begin
|
187
|
+
team_obj = octo.team(team_id(team, org))
|
188
|
+
rescue Octokit::NotFound
|
189
|
+
return response.reply(t('team_not_found', team: team))
|
190
|
+
end
|
191
|
+
|
192
|
+
begin
|
193
|
+
resp = octo.add_team_membership(team_obj[:id], username)
|
194
|
+
rescue StandardError => e
|
195
|
+
return response.reply(t('boom', m: e.message))
|
196
|
+
end
|
197
|
+
|
198
|
+
if resp
|
199
|
+
response.reply(t('org_user_add.added', u: username, o: org, t: team_obj[:name], s: team_obj[:slug]))
|
200
|
+
else
|
201
|
+
response.reply(t('org_user_add.failed', t: team_obj[:name]))
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def org_user_rm(response)
|
206
|
+
return response.reply(t('method_disabled')) if func_disabled?(__method__)
|
207
|
+
md = response.match_data
|
208
|
+
org, team, username = [organization(md['org'].strip), md['team'].strip, md['username']]
|
209
|
+
|
210
|
+
begin
|
211
|
+
user_id = octo.user(username)[:id]
|
212
|
+
rescue Octokit::NotFound
|
213
|
+
return response.reply(t('user_not_found', n: username))
|
214
|
+
end
|
215
|
+
|
216
|
+
return response.reply(t('nope')) if octo.user[:id] == user_id
|
217
|
+
|
218
|
+
begin
|
219
|
+
team = octo.team(team_id(team, org))
|
220
|
+
rescue Octokit::NotFound
|
221
|
+
return response.reply(t('team_not_found', team: team))
|
222
|
+
end
|
223
|
+
|
224
|
+
begin
|
225
|
+
resp = octo.remove_team_member(team[:id], username)
|
226
|
+
rescue StandardError => e
|
227
|
+
return response.reply(t('boom', m: e.message))
|
228
|
+
end
|
229
|
+
|
230
|
+
if resp
|
231
|
+
response.reply(t('org_user_rm.removed', u: username, o: org, t: team[:name], s: team[:slug]))
|
232
|
+
else
|
233
|
+
response.reply(t('org_user_rm.failed'), t: team[:name])
|
234
|
+
end
|
235
|
+
end
|
236
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
237
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
238
|
+
|
239
|
+
def org_eject_user(response)
|
240
|
+
return response.reply(t('method_disabled')) if func_disabled?(__method__)
|
241
|
+
md = response.match_data
|
242
|
+
org, username = [organization(md['org'].strip), md['username'].strip]
|
243
|
+
|
244
|
+
begin
|
245
|
+
user_id = octo.user(username)[:id]
|
246
|
+
rescue Octokit::NotFound
|
247
|
+
return response.reply(t('user_not_found', n: username))
|
248
|
+
end
|
249
|
+
|
250
|
+
return response.reply(t('nope')) if octo.user[:id] == user_id
|
251
|
+
|
252
|
+
begin
|
253
|
+
resp = octo.remove_organization_member(org, username)
|
254
|
+
rescue StandardError => e
|
255
|
+
return response.reply(t('boom', m: e.message))
|
256
|
+
end
|
257
|
+
|
258
|
+
if resp
|
259
|
+
response.reply(t('org_eject_user.ejected', user: username, org: org))
|
260
|
+
else
|
261
|
+
response.reply(t('org_eject_user.failed'))
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
134
265
|
private
|
135
266
|
|
136
267
|
def validate_team_add_opts(opts)
|
data/locales/en.yml
CHANGED
@@ -17,7 +17,7 @@ en:
|
|
17
17
|
company: "Company: %{c}\n"
|
18
18
|
location: "Located: %{l}\n"
|
19
19
|
account_info: "GitHub Admin: %{site_admin}, Repos: %{public_repos}, Gists: %{public_gists}\n"
|
20
|
-
user_info: "Following: %{following}, Followers: %{followers},
|
20
|
+
user_info: "Following: %{following}, Followers: %{followers}, Joined: %{created_at}"
|
21
21
|
github_repo:
|
22
22
|
method_disabled: "Sorry, this function has either been disabled or not enabled in the config"
|
23
23
|
not_found: "That repo (%{org}/%{repo}) was not found"
|
@@ -55,7 +55,8 @@ en:
|
|
55
55
|
exception: "An unexpected exception was hit during the GitHub API operation. Please make sure all arguments are proper and try again, or try checking the GitHub status (gh status)"
|
56
56
|
not_found: "Pull request #%{pr} on %{org}/%{repo} not found"
|
57
57
|
pr_info:
|
58
|
-
header: "%{repo} #%{number}: %{title} :: %{url}\n"
|
58
|
+
header: "%{repo} #%{number}: '%{title}' :: %{url}\n"
|
59
|
+
header_long: "%{repo} #%{number}: '%{title}' opened by %{u} :: %{url}\n"
|
59
60
|
status: "Opened By: %{user} | State: %{state_str} | Build: %{build_status}"
|
60
61
|
merged: " | Merged By: %{merged_by}\n"
|
61
62
|
mergeable: " | Mergeable: %{mergeable}\n"
|
@@ -71,6 +72,9 @@ en:
|
|
71
72
|
method_disabled: "Sorry, this function has either been disabled or not enabled in the config"
|
72
73
|
org_not_found: "The organization '%{org}' was not found. Does my user have ownership perms?"
|
73
74
|
team_not_found: "Unable to match any teams based on: %{team}"
|
75
|
+
user_not_found: "Unable to find the GitHub user %{n}"
|
76
|
+
nope: "No...\n\nಠ_ಠ"
|
77
|
+
boom: "I had a problem :( ... %{m}"
|
74
78
|
org_teams_list:
|
75
79
|
header: "Showing %{num_teams} team(s) for %{org}:\n"
|
76
80
|
team: "Name: %{name}, Slug: %{slug}, ID: %{id}, Perms: %{permission}\n"
|
@@ -82,3 +86,23 @@ en:
|
|
82
86
|
org_team_rm:
|
83
87
|
pass: "The '%{name}' team was deleted. Its ID was %{id}"
|
84
88
|
fail: "Something went wrong trying to delete the '%{name}' team. Is Github having issues?"
|
89
|
+
org_eject_user:
|
90
|
+
ejected: "Ejected %{user} out of %{org}"
|
91
|
+
failed: "Failed to eject the user from the organization for an unknown reason"
|
92
|
+
org_user_rm:
|
93
|
+
removed: "%{u} has been removed from the '%{o}/%{t}' (%{s}) team"
|
94
|
+
failed: "Failed to remove the user from the '%{t}' team for some unknown reason"
|
95
|
+
org_user_add:
|
96
|
+
added: "%{u} has been added to the '%{o}/%{t}' (%{s}) team"
|
97
|
+
failed: "Failed to add the user to the '%{t}' team for some unknown reason"
|
98
|
+
github_issues:
|
99
|
+
repo_not_found: "That repo (%{repo}) was not found"
|
100
|
+
boom: "I had a problem :( ... %{m}"
|
101
|
+
issues_list:
|
102
|
+
none: "There are no open issues for %{r}"
|
103
|
+
header: "Showing %{n} issue(s) for %{r}\n"
|
104
|
+
item: "%{r} #%{number}: '%{title}' opened by %{u} :: %{html_url}\n"
|
105
|
+
val_states: "Issues can be one of the following states: 'open', 'closed', or 'all'\n"
|
106
|
+
val_sort: "Issues can be sorted by one of the following: 'created', 'updated', 'comments'\n"
|
107
|
+
val_direction: "Issues can be ordered either 'asc' (ascending) or 'desc' (descending)\n"
|
108
|
+
invalid_opts: "An invalid option was provided, here's the error from Octokit:\n%{m}"
|