lita-jls 0.0.11
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 +7 -0
- data/.gitignore +19 -0
- data/Gemfile +3 -0
- data/LICENSE +19 -0
- data/README.md +24 -0
- data/Rakefile +6 -0
- data/lib/lita-jls.rb +8 -0
- data/lib/lita-jls/bot_builder.rb +240 -0
- data/lib/lita-jls/github_url_parser.rb +43 -0
- data/lib/lita-jls/repository.rb +57 -0
- data/lib/lita-jls/util.rb +259 -0
- data/lib/lita/handlers/jls.rb +321 -0
- data/lita-jls.gemspec +41 -0
- data/locales/en.yml +4 -0
- data/spec/fixtures/bad_project/Gemfile +2 -0
- data/spec/fixtures/logstash-codec-edn/logstash-codec-edn.gemspec +29 -0
- data/spec/fixtures/logstash.gemspec +3 -0
- data/spec/fixtures/project_with_version_file/lib/testmore/version.rb +3 -0
- data/spec/fixtures/project_with_version_file/project_with_version_file.gemspec +9 -0
- data/spec/fixtures/vcr_cassettes/fetch_version_of_logstash-output-s3.yml +96 -0
- data/spec/fixtures/vcr_cassettes/gem_doesnt_exist.yml +57 -0
- data/spec/fixtures/vcr_cassettes/successful_clacheck.yml +127 -0
- data/spec/fixtures/vcr_cassettes/successful_clacheck_long_commit.yml +133 -0
- data/spec/fixtures/vcr_cassettes/successful_migrate_pr.yml +81 -0
- data/spec/lita-jls/bot_builder_spec.rb +158 -0
- data/spec/lita-jls/github_url_parser_spec.rb +80 -0
- data/spec/lita/handlers/jls_spec.rb +211 -0
- data/spec/spec_helper.rb +31 -0
- metadata +338 -0
@@ -0,0 +1,321 @@
|
|
1
|
+
require "cabin"
|
2
|
+
require "tmpdir"
|
3
|
+
require "tempfile"
|
4
|
+
require "fileutils"
|
5
|
+
require "insist"
|
6
|
+
require "uri"
|
7
|
+
require "lita-jls/bot_builder"
|
8
|
+
require "lita-jls/repository"
|
9
|
+
require "lita-jls/github_url_parser"
|
10
|
+
require "lita-jls/util"
|
11
|
+
|
12
|
+
# TODO(sissel): This code needs some suuuper serious refactoring and testing improvements.
|
13
|
+
# TODO(sissel): Remove any usage of Rugged. This library requires compile-time
|
14
|
+
# settings of libgit2 and that's an annoying battle.
|
15
|
+
|
16
|
+
module Lita
|
17
|
+
module Handlers
|
18
|
+
class Jls < Handler
|
19
|
+
include LitaJLS::Util
|
20
|
+
|
21
|
+
route /^merge(?<dry>\?)? (?<pr_url>[^ ]+) (?<branchspec>.*)$/, :merge,
|
22
|
+
:command => true,
|
23
|
+
:help => { "merge https://github.com/ORG/PROJECT/pull/NUMBER branch1 [branch2 ...]" => "merges a PR into one or more branches. To see if a merge is successful, use 'merge? project#pr branch1 [branch2 ...]" }
|
24
|
+
|
25
|
+
route /^cla(?<dry>\?)? (?<pr_url>[^ ]+)$/, :cla,
|
26
|
+
:command => true,
|
27
|
+
:help => { "cla https://github.com/ORG/PROJECT/pull/NUMBER" => "CLA check for a giaven PR" }
|
28
|
+
|
29
|
+
route /^\(tableflip\)$/, :tableflip,
|
30
|
+
:command => true,
|
31
|
+
:help => { "(tableflip)" => "Fix whatever just broke. Probably git is going funky, so I will purge my local git junk" }
|
32
|
+
|
33
|
+
route /^ping/, :ping, :command => true
|
34
|
+
|
35
|
+
route /^publish\s(?<git_url>[^ ]+)$/, :publish,
|
36
|
+
:command => true,
|
37
|
+
:restrict_to => :logstash,
|
38
|
+
:help => { 'publish https://github.com/ORG/project' => 'Install dependencies, Run test, build gem, publish and compare version on rubygems' }
|
39
|
+
|
40
|
+
route /^(why computer(s?) so bad\?|explain)/i, :pop_exception,
|
41
|
+
:command => true,
|
42
|
+
:help => { 'explain or why computers so bad?' => 'return the last exception from redis' }
|
43
|
+
|
44
|
+
route /^migrate_pr (?<source_url>[^ ]+) (?<destination_url>[^ ]+)$/, :migrate_pr,
|
45
|
+
:command => true,
|
46
|
+
:help => { 'migrate_pr https://github.com/elasticsearch/logstash/pull/1452 "\
|
47
|
+
+ "https://github.com/logstash-plugins/logstash-codec-line' => 'migrate pr from one repo to another' }
|
48
|
+
|
49
|
+
REMOTE = "origin"
|
50
|
+
URLBASE = "https://github.com/"
|
51
|
+
LIMIT_EXCEPTIONS_HISTORY = 20
|
52
|
+
|
53
|
+
RUBY_VERSION = "jruby-1.7.16"
|
54
|
+
|
55
|
+
on :loaded, :setup
|
56
|
+
|
57
|
+
def self.default_config(config)
|
58
|
+
config.default_organization = nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def pop_exception(msg)
|
62
|
+
public_response = ['Commencing automated assembly. Estimated completion time is five hours.',
|
63
|
+
'That is the only way, sir.',
|
64
|
+
'Sir, please may I request just a few hours to calibrate.' ]
|
65
|
+
|
66
|
+
e = @redis.lpop(:exception)
|
67
|
+
|
68
|
+
msg.reply(public_response.sample)
|
69
|
+
|
70
|
+
logger.debug("pop exception", :exception => e)
|
71
|
+
|
72
|
+
if e
|
73
|
+
e = JSON.parse(e)
|
74
|
+
|
75
|
+
msg.reply_privately("exception: #{e.delete('exception')}")
|
76
|
+
msg.reply_privately("message: #{e.delete('message')}")
|
77
|
+
msg.reply_privately("backtrace: #{e.delete('backtrace')}")
|
78
|
+
|
79
|
+
# Print the remaining context
|
80
|
+
e.each do |key, value|
|
81
|
+
msg.reply_privately("#{key}: #{value}")
|
82
|
+
end
|
83
|
+
else
|
84
|
+
msg.reply_privately("No exception saved.")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def push_exception(e, context = {})
|
89
|
+
error = {
|
90
|
+
"exception" => e.exception,
|
91
|
+
"message" => e.message,
|
92
|
+
"backtrace" => e.backtrace,
|
93
|
+
}.merge(context)
|
94
|
+
|
95
|
+
@redis.lpush(:exception, error.to_json)
|
96
|
+
@redis.ltrim(:exception, 0, LIMIT_EXCEPTIONS_HISTORY)
|
97
|
+
end
|
98
|
+
|
99
|
+
def publish(msg)
|
100
|
+
git_url = msg.match_data["git_url"]
|
101
|
+
|
102
|
+
logger.info('publish', :url => git_url)
|
103
|
+
|
104
|
+
github_parser = LitaJLS::GithubUrlParser.parse(git_url, :link => :repository)
|
105
|
+
github_parser.validate!
|
106
|
+
|
107
|
+
repository = LitaJLS::Repository.new(github_parser)
|
108
|
+
repository.clone
|
109
|
+
repository.switch_branch('master')
|
110
|
+
|
111
|
+
builder = LitaJLS::BotBuilder.new(repository.git_path, { :ruby_version => RUBY_VERSION })
|
112
|
+
|
113
|
+
msg.reply("publishing (allthethings) for project: #{builder.project_name} branch: master")
|
114
|
+
|
115
|
+
reporter = LitaJLS::Reporter::HipChat.new(builder.build)
|
116
|
+
reporter.format(msg)
|
117
|
+
rescue => e
|
118
|
+
push_exception(e, :project => "#{github_parser.user}/#{github_parser.project}")
|
119
|
+
msg.reply("(stare) Error: #{e.inspect}")
|
120
|
+
raise
|
121
|
+
end # def publish
|
122
|
+
|
123
|
+
def ping(msg)
|
124
|
+
msg.reply("(chompy)")
|
125
|
+
end
|
126
|
+
|
127
|
+
def setup(*args)
|
128
|
+
ENV["PAGER"] = "cat"
|
129
|
+
@@logger_subscription ||= logger.subscribe(STDOUT)
|
130
|
+
|
131
|
+
@redis ||= Redis::Namespace.new("opsbot", redis: Lita.redis)
|
132
|
+
end
|
133
|
+
|
134
|
+
def cla(msg)
|
135
|
+
@cla_uri = config.cla_uri
|
136
|
+
pull = msg.match_data["pr_url"]
|
137
|
+
pull_path = URI.parse(pull).path
|
138
|
+
_, user, project, _, pr = pull_path.split("/")
|
139
|
+
cla?("#{user}/#{project}", pr)
|
140
|
+
msg.reply("#{user}/#{project}##{pr} CLA OK (freddie)")
|
141
|
+
rescue => e
|
142
|
+
msg.reply("cla check error: #{e}")
|
143
|
+
push_exception(e, :project => "#{user}/#{project}", :pr => pr)
|
144
|
+
end
|
145
|
+
|
146
|
+
def migrate_pr(msg)
|
147
|
+
source_url = msg.match_data["source_url"]
|
148
|
+
destination_url = msg.match_data["destination_url"]
|
149
|
+
if source_url.nil? || destination_url.nil?
|
150
|
+
raise "Invalid paramaters provided #{msg}"
|
151
|
+
end
|
152
|
+
|
153
|
+
destination_github_parser = parse_github_url(destination_url)
|
154
|
+
source_github_parser = parse_github_url(source_url)
|
155
|
+
|
156
|
+
pr_num = source_github_parser.pr
|
157
|
+
source_github_pr = github_get_pr("#{source_github_parser.user}/#{source_github_parser.project}", pr_num)
|
158
|
+
|
159
|
+
# Clone destination dir, patch and then push branch
|
160
|
+
repository = LitaJLS::Repository.new(destination_github_parser)
|
161
|
+
repository.clone if Dir["#{repository.git_path}/*"].empty?
|
162
|
+
repository.switch_branch("master")
|
163
|
+
|
164
|
+
# create a branch like pr/1234
|
165
|
+
pr_branch = "bot-migrated-pr/#{pr_num}"
|
166
|
+
repository.delete_local_branch(pr_branch, true)
|
167
|
+
repository.switch_branch(pr_branch, true)
|
168
|
+
|
169
|
+
patch_file = download_patch(source_github_pr[:patch_url], pr_num)
|
170
|
+
|
171
|
+
# Apply patch on repo
|
172
|
+
begin
|
173
|
+
repository.git_patch(patch_file.path)
|
174
|
+
repository.git_push_branch(pr_branch)
|
175
|
+
rescue => e
|
176
|
+
msg.reply("Error while migrating pr: #{e}")
|
177
|
+
push_exception(e, :source_url => source_url,
|
178
|
+
:destination_url => destination_url)
|
179
|
+
ensure
|
180
|
+
patch_file.unlink
|
181
|
+
end
|
182
|
+
|
183
|
+
# create the migrated PR in the destination repo
|
184
|
+
github_create_pr("#{destination_github_parser.user}/#{destination_github_parser.project}",
|
185
|
+
pr_branch, source_github_pr[:title],
|
186
|
+
source_github_pr[:body] + "\nMoved from #{source_url}")
|
187
|
+
end
|
188
|
+
|
189
|
+
@private
|
190
|
+
# downloads the patch file in mail format and saves it to a file
|
191
|
+
def download_patch(pr_url, pr_num)
|
192
|
+
http = Faraday.new("https://github.com")
|
193
|
+
response = http.get(URI.parse(pr_url).path)
|
194
|
+
if response.status != 200
|
195
|
+
raise "Unable to fetch pull request #{pr_url}"
|
196
|
+
end
|
197
|
+
|
198
|
+
patch_file = Tempfile.new("#{pr_num}.patch")
|
199
|
+
|
200
|
+
begin
|
201
|
+
#TODO: Use chunked writes
|
202
|
+
patch_file.write(response.body)
|
203
|
+
patch_file.close
|
204
|
+
rescue => e
|
205
|
+
raise "Error while downloading pr: #{pr_url}, exception #{e}"
|
206
|
+
end
|
207
|
+
|
208
|
+
return patch_file
|
209
|
+
end
|
210
|
+
|
211
|
+
@private
|
212
|
+
def parse_github_url(url)
|
213
|
+
github_parser = LitaJLS::GithubUrlParser.parse(url, :link => :repository)
|
214
|
+
github_parser.validate!
|
215
|
+
return github_parser
|
216
|
+
end
|
217
|
+
|
218
|
+
def merge(msg)
|
219
|
+
@cla_uri = config.cla_uri
|
220
|
+
FileUtils.mkdir_p(workdir) unless File.directory?(workdir)
|
221
|
+
pull = msg.match_data["pr_url"]
|
222
|
+
pull_path = URI.parse(pull).path
|
223
|
+
_, user, project, _, pr = pull_path.split("/")
|
224
|
+
|
225
|
+
if user.nil? || project.nil? || pr.nil? || pull !~ /^https:\/\/github.com\//
|
226
|
+
raise "Invalid URL. Expected something like: https://github.com/elasticsearch/snacktime/pull/12345"
|
227
|
+
end
|
228
|
+
|
229
|
+
branchspec = msg.match_data["branchspec"]
|
230
|
+
dry_run = msg.match_data["dry"]
|
231
|
+
|
232
|
+
begin
|
233
|
+
cla?("#{user}/#{project}", pr)
|
234
|
+
rescue => e
|
235
|
+
msg.reply("(firstworldproblems) cla check failed for #{user}/#{project}##{pr}.\n #{e}")
|
236
|
+
push_exception(e, :project => "#{user}/#{project}", :pr => pr)
|
237
|
+
return
|
238
|
+
end
|
239
|
+
|
240
|
+
url = File.join(URLBASE, user, project)
|
241
|
+
#git_url = "git@github.com:/#{user}/#{project}.git"
|
242
|
+
git_url = url
|
243
|
+
pr_url = File.join(url, "pull", "#{pr}.patch")
|
244
|
+
gitpath = gitdir(project)
|
245
|
+
branches = branchspec.split(/\s+/)
|
246
|
+
|
247
|
+
logger.info("Cloning git repo", :url => git_url, :gitpath => gitpath)
|
248
|
+
repo = clone_at(git_url, gitpath)
|
249
|
+
|
250
|
+
git(gitpath, "am", "--abort") if File.directory?(".git/rebase-apply")
|
251
|
+
|
252
|
+
# TODO(sissel): Fetch the PR patch
|
253
|
+
logger.info("Fetching PR patch", :url => pr_url)
|
254
|
+
http = Faraday.new("https://github.com")
|
255
|
+
response = http.get(URI.parse(pr_url).path)
|
256
|
+
if !response.success?
|
257
|
+
logger.warn("Failed fetching patch", :url => pr_url, :status => response.status, :headers => response.headers)
|
258
|
+
msg.reply("(grumpycat) Failed fetching patch. Cannot continue!")
|
259
|
+
return
|
260
|
+
end
|
261
|
+
|
262
|
+
patch = response.body
|
263
|
+
|
264
|
+
# For each branch, try to merge
|
265
|
+
repo = gitpath
|
266
|
+
branches.each do |branch|
|
267
|
+
begin
|
268
|
+
logger.info("Switching branches", :branch => branch, :repo => gitpath)
|
269
|
+
git(gitpath, "checkout", branch)
|
270
|
+
git(gitpath, "reset", "--hard", "#{REMOTE}/#{branch}")
|
271
|
+
git(gitpath, "pull", "--ff-only")
|
272
|
+
apply_patch(repo, patch) do |commit|
|
273
|
+
# Append the PR number to commit message
|
274
|
+
|
275
|
+
# Use "Fixes #XYZ" to make the PR get closed upon commit.
|
276
|
+
# https://help.github.com/articles/closing-issues-via-commit-messages
|
277
|
+
commit[:message] += "\nFixes ##{pr}"
|
278
|
+
end
|
279
|
+
rescue => e
|
280
|
+
push_exception(e, :project => "#{user}/#{project}", :pr => pr, :branch => branch)
|
281
|
+
msg.reply("(jackie) Failed attempting to merge #{user}/#{project}##{pr} into #{branch}: #{e}")
|
282
|
+
raise
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
# At this point, all branches merged successfully. Time to push!
|
287
|
+
if dry_run
|
288
|
+
msg.reply("(success) Merging was successful #{user}/#{project}##{pr} into: #{branchspec}.\n(but I did not push it)")
|
289
|
+
else
|
290
|
+
msg.reply("(success) #{user}/#{project}##{pr} merged into: #{branchspec}")
|
291
|
+
git(gitpath, "push", REMOTE, *branches)
|
292
|
+
|
293
|
+
labels = branches.reject { |b| b == "master" }
|
294
|
+
github_issue_label("#{user}/#{project}", pr.to_i, labels)
|
295
|
+
end
|
296
|
+
github_issue_comment("#{user}/#{project}", pr.to_i, "Merged sucessfully into #{branchspec}!")
|
297
|
+
rescue => e
|
298
|
+
push_exception(e, :project => "#{user}/#{project}", :pr => pr, :branch => branches)
|
299
|
+
msg.reply("(stare) Error: #{e.inspect}")
|
300
|
+
raise
|
301
|
+
end # def merge
|
302
|
+
|
303
|
+
def tableflip(msg)
|
304
|
+
logger.debug("(fliptable), remove the git directory")
|
305
|
+
|
306
|
+
begin
|
307
|
+
dir = workdir("gitbase")
|
308
|
+
insist { dir } =~ /\/lita-jls/ # Just in case, before we go purging things...
|
309
|
+
FileUtils.rm_r(dir) if File.directory?(dir)
|
310
|
+
msg.reply("Git: (tableflip) (success)")
|
311
|
+
rescue => e
|
312
|
+
push_exception(e)
|
313
|
+
msg.reply("Git: (tableflip) (huh): #{e}")
|
314
|
+
raise e
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end # class Jls
|
318
|
+
|
319
|
+
Lita.register_handler(Jls)
|
320
|
+
end
|
321
|
+
end
|
data/lita-jls.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
Gem::Specification.new do |spec|
|
2
|
+
spec.name = "lita-jls"
|
3
|
+
spec.version = "0.0.11"
|
4
|
+
spec.authors = ["Jordan Sissel"]
|
5
|
+
spec.email = ["jls@semicomplete.com"]
|
6
|
+
spec.description = %q{Some stuff for the lita.io bot}
|
7
|
+
spec.summary = spec.description
|
8
|
+
spec.homepage = "http://example.com/"
|
9
|
+
spec.license = "MIT"
|
10
|
+
spec.metadata = { "lita_plugin_type" => "handler" }
|
11
|
+
|
12
|
+
spec.files = `git ls-files`.split($/)
|
13
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
14
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
15
|
+
spec.require_paths = ["lib"]
|
16
|
+
|
17
|
+
spec.add_runtime_dependency "lita", ">= 3.3"
|
18
|
+
spec.add_runtime_dependency "cabin", ">= 0"
|
19
|
+
spec.add_runtime_dependency "faraday", ">= 0"
|
20
|
+
|
21
|
+
# For access to Github's api
|
22
|
+
spec.add_runtime_dependency "octokit", ">= 0"
|
23
|
+
# For netrc support in octokit
|
24
|
+
spec.add_runtime_dependency "netrc"
|
25
|
+
|
26
|
+
# For parsing github's .patch files (mbox format)
|
27
|
+
spec.add_runtime_dependency "mbox", ">= 0"
|
28
|
+
spec.add_runtime_dependency "insist"
|
29
|
+
spec.add_runtime_dependency 'gems', '~> 0.8.3'
|
30
|
+
spec.add_runtime_dependency 'semverly', '~> 1.0.0'
|
31
|
+
|
32
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
33
|
+
spec.add_development_dependency "rake"
|
34
|
+
spec.add_development_dependency "stud"
|
35
|
+
spec.add_development_dependency "rspec", ">= 3.0.0"
|
36
|
+
spec.add_development_dependency "simplecov"
|
37
|
+
spec.add_development_dependency "pry"
|
38
|
+
spec.add_development_dependency "coveralls"
|
39
|
+
spec.add_development_dependency "vcr"
|
40
|
+
spec.add_development_dependency "webmock"
|
41
|
+
end
|
data/locales/en.yml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
|
3
|
+
s.name = 'logstash-codec-edn'
|
4
|
+
s.version = '0.1.3'
|
5
|
+
s.licenses = ['Apache License (2.0)']
|
6
|
+
s.summary = "Codec to process EDN data"
|
7
|
+
s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
|
8
|
+
s.authors = ["Elasticsearch"]
|
9
|
+
s.email = 'info@elasticsearch.com'
|
10
|
+
s.homepage = "http://www.elasticsearch.org/guide/en/logstash/current/index.html"
|
11
|
+
s.require_paths = ["lib"]
|
12
|
+
|
13
|
+
# Files
|
14
|
+
s.files = `git ls-files`.split($\)
|
15
|
+
|
16
|
+
# Tests
|
17
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
18
|
+
|
19
|
+
# Special flag to let us know this is actually a logstash plugin
|
20
|
+
s.metadata = { "logstash_plugin" => "true", "logstash_group" => "codec" }
|
21
|
+
|
22
|
+
# Gem dependencies
|
23
|
+
s.add_runtime_dependency 'logstash', '>= 1.4.0', '< 2.0.0'
|
24
|
+
|
25
|
+
s.add_runtime_dependency 'edn'
|
26
|
+
|
27
|
+
s.add_development_dependency 'logstash-devutils'
|
28
|
+
end
|
29
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'testmore/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dummy-gem-dont-publish"
|
8
|
+
spec.version = Testmore::VERSION
|
9
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://rubygems.org/api/v1/versions/logstash-output-s3.yaml
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept-Encoding:
|
11
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
12
|
+
Accept:
|
13
|
+
- "*/*"
|
14
|
+
User-Agent:
|
15
|
+
- Gems 0.8.3
|
16
|
+
- Ruby
|
17
|
+
Connection:
|
18
|
+
- keep-alive
|
19
|
+
Keep-Alive:
|
20
|
+
- '30'
|
21
|
+
Content-Type:
|
22
|
+
- application/x-www-form-urlencoded
|
23
|
+
response:
|
24
|
+
status:
|
25
|
+
code: 200
|
26
|
+
message: OK
|
27
|
+
headers:
|
28
|
+
Server:
|
29
|
+
- nginx
|
30
|
+
Date:
|
31
|
+
- Tue, 16 Dec 2014 16:12:50 GMT
|
32
|
+
Content-Type:
|
33
|
+
- text/yaml
|
34
|
+
Transfer-Encoding:
|
35
|
+
- chunked
|
36
|
+
Connection:
|
37
|
+
- keep-alive
|
38
|
+
Status:
|
39
|
+
- 200 OK
|
40
|
+
Etag:
|
41
|
+
- '"7341898c9b8c18bb4a2f72cafa13f98e"'
|
42
|
+
Last-Modified:
|
43
|
+
- Thu, 06 Nov 2014 09:33:38 GMT
|
44
|
+
Content-Disposition:
|
45
|
+
- attachment
|
46
|
+
Content-Transfer-Encoding:
|
47
|
+
- binary
|
48
|
+
Cache-Control:
|
49
|
+
- private
|
50
|
+
X-Content-Type-Options:
|
51
|
+
- nosniff
|
52
|
+
X-Ua-Compatible:
|
53
|
+
- IE=Edge,chrome=1
|
54
|
+
- IE=Edge,chrome=1
|
55
|
+
X-Request-Id:
|
56
|
+
- e726d0892877a0b310402be784f88add
|
57
|
+
X-Runtime:
|
58
|
+
- '0.012082'
|
59
|
+
X-Rack-Cache:
|
60
|
+
- miss
|
61
|
+
body:
|
62
|
+
encoding: UTF-8
|
63
|
+
string: |
|
64
|
+
---
|
65
|
+
- authors: Elasticsearch
|
66
|
+
built_at: '2014-11-19T00:00:00Z'
|
67
|
+
description: This gem is a logstash plugin required to be installed on top of the
|
68
|
+
Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is
|
69
|
+
not a stand-alone program
|
70
|
+
downloads_count: 479
|
71
|
+
number: 0.1.1
|
72
|
+
summary: This plugin was created for store the logstash's events into Amazon Simple
|
73
|
+
Storage Service (Amazon S3)
|
74
|
+
platform: ruby
|
75
|
+
ruby_version: '>= 0'
|
76
|
+
prerelease: false
|
77
|
+
licenses:
|
78
|
+
- Apache License (2.0)
|
79
|
+
requirements: []
|
80
|
+
- authors: Elasticsearch
|
81
|
+
built_at: '2014-11-06T00:00:00Z'
|
82
|
+
description: This plugin was created for store the logstash's events into Amazon
|
83
|
+
Simple Storage Service (Amazon S3)
|
84
|
+
downloads_count: 195
|
85
|
+
number: 0.1.0
|
86
|
+
summary: This plugin was created for store the logstash's events into Amazon Simple
|
87
|
+
Storage Service (Amazon S3)
|
88
|
+
platform: ruby
|
89
|
+
ruby_version: '>= 0'
|
90
|
+
prerelease: false
|
91
|
+
licenses:
|
92
|
+
- Apache License (2.0)
|
93
|
+
requirements: []
|
94
|
+
http_version:
|
95
|
+
recorded_at: Tue, 16 Dec 2014 16:12:51 GMT
|
96
|
+
recorded_with: VCR 2.9.3
|