airbrake-ruby 2.11.0 → 2.12.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 +4 -4
- data/lib/airbrake-ruby.rb +2 -0
- data/lib/airbrake-ruby/config.rb +1 -1
- data/lib/airbrake-ruby/filters/git_last_checkout_filter.rb +88 -0
- data/lib/airbrake-ruby/filters/git_repository_filter.rb +34 -0
- data/lib/airbrake-ruby/filters/git_revision_filter.rb +10 -2
- data/lib/airbrake-ruby/notifier.rb +14 -7
- data/lib/airbrake-ruby/version.rb +1 -1
- data/spec/config_spec.rb +1 -1
- data/spec/filters/git_last_checkout_filter_spec.rb +48 -0
- data/spec/filters/git_repository_filter.rb +35 -0
- data/spec/notifier_spec.rb +27 -11
- data/spec/notifier_spec/options_spec.rb +1 -1
- data/spec/sync_sender_spec.rb +2 -2
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f92ef10b01c37b9374a6662bedba21c1593ef34
|
4
|
+
data.tar.gz: 957da6a830307c3d3cd9f583f1eaa9bf4a2df96f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0ca6c8f84dfc39758f22203519765820a25c4bddd8e7aae90928d46b1f201ee7ab283679fdc16020043cd222c3a6f3e09def0642d1428d005b3022b8dfc59ee
|
7
|
+
data.tar.gz: 46f263d46199864c89c70c721ecb1c50f13262a13b9b3603b31260cd0f6ea44536fa2ceb419b3efaee1bd82b7877f53246c754288f433054c43ca3b0af3bba58
|
data/lib/airbrake-ruby.rb
CHANGED
@@ -27,6 +27,8 @@ require 'airbrake-ruby/filters/context_filter'
|
|
27
27
|
require 'airbrake-ruby/filters/exception_attributes_filter'
|
28
28
|
require 'airbrake-ruby/filters/dependency_filter'
|
29
29
|
require 'airbrake-ruby/filters/git_revision_filter'
|
30
|
+
require 'airbrake-ruby/filters/git_repository_filter'
|
31
|
+
require 'airbrake-ruby/filters/git_last_checkout_filter'
|
30
32
|
require 'airbrake-ruby/filter_chain'
|
31
33
|
require 'airbrake-ruby/notifier'
|
32
34
|
require 'airbrake-ruby/code_hunk'
|
data/lib/airbrake-ruby/config.rb
CHANGED
@@ -0,0 +1,88 @@
|
|
1
|
+
module Airbrake
|
2
|
+
module Filters
|
3
|
+
# Attaches git checkout info to `context`. The info includes:
|
4
|
+
# * username
|
5
|
+
# * email
|
6
|
+
# * revision
|
7
|
+
# * time
|
8
|
+
#
|
9
|
+
# This information is used to track deploys automatically.
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since v2.12.0
|
13
|
+
class GitLastCheckoutFilter
|
14
|
+
# @return [Integer]
|
15
|
+
attr_reader :weight
|
16
|
+
|
17
|
+
# @return [Integer] least possible amount of columns in git's `logs/HEAD`
|
18
|
+
# file (checkout information is omitted)
|
19
|
+
MIN_HEAD_COLS = 6
|
20
|
+
|
21
|
+
# @param [Logger] logger
|
22
|
+
# @param [String] root_directory
|
23
|
+
def initialize(logger, root_directory)
|
24
|
+
@git_path = File.join(root_directory, '.git')
|
25
|
+
@logger = logger
|
26
|
+
@weight = 116
|
27
|
+
@last_checkout = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# @macro call_filter
|
31
|
+
def call(notice)
|
32
|
+
return if notice[:context].key?(:lastCheckout)
|
33
|
+
|
34
|
+
if @last_checkout
|
35
|
+
notice[:context][:lastCheckout] = @last_checkout
|
36
|
+
return
|
37
|
+
end
|
38
|
+
|
39
|
+
return unless File.exist?(@git_path)
|
40
|
+
return unless (checkout = last_checkout)
|
41
|
+
notice[:context][:lastCheckout] = checkout
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def last_checkout
|
47
|
+
return unless (line = last_checkout_line)
|
48
|
+
|
49
|
+
parts = line.chomp.split("\t").first.split(' ')
|
50
|
+
if parts.size < MIN_HEAD_COLS
|
51
|
+
@logger.error(
|
52
|
+
"#{LOG_LABEL} Airbrake::#{self.class.name}: can't parse line: #{line}"
|
53
|
+
)
|
54
|
+
return
|
55
|
+
end
|
56
|
+
|
57
|
+
author = parts[2..-4]
|
58
|
+
@last_checkout = {
|
59
|
+
username: author[0..1].join(' '),
|
60
|
+
email: parts[-3][1..-2],
|
61
|
+
revision: parts[1],
|
62
|
+
time: timestamp(parts[-2].to_i)
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def last_checkout_line
|
67
|
+
head_path = File.join(@git_path, 'logs', 'HEAD')
|
68
|
+
return unless File.exist?(head_path)
|
69
|
+
|
70
|
+
last_line = nil
|
71
|
+
IO.foreach(head_path) do |line|
|
72
|
+
last_line = line if checkout_line?(line)
|
73
|
+
end
|
74
|
+
last_line
|
75
|
+
end
|
76
|
+
|
77
|
+
def checkout_line?(line)
|
78
|
+
line.include?("\tclone:") ||
|
79
|
+
line.include?("\tpull:") ||
|
80
|
+
line.include?("\tcheckout:")
|
81
|
+
end
|
82
|
+
|
83
|
+
def timestamp(utime)
|
84
|
+
Time.at(utime).to_datetime.rfc3339
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Airbrake
|
2
|
+
module Filters
|
3
|
+
# Attaches git repository URL to `context`.
|
4
|
+
# @api private
|
5
|
+
# @since v2.12.0
|
6
|
+
class GitRepositoryFilter
|
7
|
+
# @return [Integer]
|
8
|
+
attr_reader :weight
|
9
|
+
|
10
|
+
# @param [String] root_directory
|
11
|
+
def initialize(root_directory)
|
12
|
+
@git_path = File.join(root_directory, '.git')
|
13
|
+
@repository = nil
|
14
|
+
@weight = 116
|
15
|
+
end
|
16
|
+
|
17
|
+
# @macro call_filter
|
18
|
+
def call(notice)
|
19
|
+
return if notice[:context].key?(:repository)
|
20
|
+
|
21
|
+
if @repository
|
22
|
+
notice[:context][:repository] = @repository
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
return unless File.exist?(@git_path)
|
27
|
+
|
28
|
+
@repository = `cd #{@git_path} && git remote get-url origin`.chomp
|
29
|
+
return unless @repository
|
30
|
+
notice[:context][:repository] = @repository
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -13,16 +13,24 @@ module Airbrake
|
|
13
13
|
# @param [String] root_directory
|
14
14
|
def initialize(root_directory)
|
15
15
|
@git_path = File.join(root_directory, '.git')
|
16
|
+
@revision = nil
|
16
17
|
@weight = 116
|
17
18
|
end
|
18
19
|
|
19
20
|
# @macro call_filter
|
20
21
|
def call(notice)
|
21
22
|
return if notice[:context].key?(:revision)
|
23
|
+
|
24
|
+
if @revision
|
25
|
+
notice[:context][:revision] = @revision
|
26
|
+
return
|
27
|
+
end
|
28
|
+
|
22
29
|
return unless File.exist?(@git_path)
|
23
30
|
|
24
|
-
revision = find_revision
|
25
|
-
|
31
|
+
@revision = find_revision
|
32
|
+
return unless @revision
|
33
|
+
notice[:context][:revision] = @revision
|
26
34
|
end
|
27
35
|
|
28
36
|
private
|
@@ -76,9 +76,12 @@ module Airbrake
|
|
76
76
|
# @macro see_public_api_method
|
77
77
|
def create_deploy(deploy_params)
|
78
78
|
deploy_params[:environment] ||= @config.environment
|
79
|
-
path = "api/v4/projects/#{@config.project_id}/deploys?key=#{@config.project_key}"
|
80
79
|
promise = Airbrake::Promise.new
|
81
|
-
@sync_sender.send(
|
80
|
+
@sync_sender.send(
|
81
|
+
deploy_params,
|
82
|
+
promise,
|
83
|
+
URI.join(@config.host, "api/v4/projects/#{@config.project_id}/deploys")
|
84
|
+
)
|
82
85
|
promise
|
83
86
|
end
|
84
87
|
|
@@ -115,8 +118,8 @@ module Airbrake
|
|
115
118
|
end
|
116
119
|
|
117
120
|
notice = build_notice(exception, params)
|
121
|
+
yield notice if block_given?
|
118
122
|
@filter_chain.refine(notice)
|
119
|
-
yield notice if block_given? && !notice.ignored?
|
120
123
|
|
121
124
|
return promise.reject("#{notice} was marked as ignored") if notice.ignored?
|
122
125
|
|
@@ -163,12 +166,16 @@ module Airbrake
|
|
163
166
|
)
|
164
167
|
|
165
168
|
return unless (root_directory = @config.root_directory)
|
166
|
-
|
167
|
-
Airbrake::Filters::RootDirectoryFilter
|
168
|
-
|
169
|
+
[
|
170
|
+
Airbrake::Filters::RootDirectoryFilter,
|
171
|
+
Airbrake::Filters::GitRevisionFilter,
|
172
|
+
Airbrake::Filters::GitRepositoryFilter
|
173
|
+
].each do |filter|
|
174
|
+
@filter_chain.add_filter(filter.new(root_directory))
|
175
|
+
end
|
169
176
|
|
170
177
|
@filter_chain.add_filter(
|
171
|
-
Airbrake::Filters::
|
178
|
+
Airbrake::Filters::GitLastCheckoutFilter.new(@config.logger, root_directory)
|
172
179
|
)
|
173
180
|
end
|
174
181
|
# rubocop:enable Metrics/AbcSize
|
data/spec/config_spec.rb
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Airbrake::Filters::GitLastCheckoutFilter do
|
4
|
+
subject { described_class.new(Logger.new(STDOUT), '.') }
|
5
|
+
|
6
|
+
let(:notice) do
|
7
|
+
Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
|
8
|
+
end
|
9
|
+
|
10
|
+
context "when context/lastCheckout is defined" do
|
11
|
+
it "doesn't attach anything to context/lastCheckout" do
|
12
|
+
notice[:context][:lastCheckout] = '123'
|
13
|
+
subject.call(notice)
|
14
|
+
expect(notice[:context][:lastCheckout]).to eq('123')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when .git directory doesn't exist" do
|
19
|
+
subject { described_class.new(Logger.new(STDOUT), 'root/dir') }
|
20
|
+
|
21
|
+
it "doesn't attach anything to context/lastCheckout" do
|
22
|
+
subject.call(notice)
|
23
|
+
expect(notice[:context][:lastCheckout]).to be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when .git directory exists" do
|
28
|
+
before { subject.call(notice) }
|
29
|
+
|
30
|
+
it "attaches last checkouted username" do
|
31
|
+
expect(notice[:context][:lastCheckout][:username]).not_to be_empty
|
32
|
+
end
|
33
|
+
|
34
|
+
it "attaches last checkouted email" do
|
35
|
+
expect(notice[:context][:lastCheckout][:email]).to match(/\A\w+@\w+\.?\w+?\z/)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "attaches last checkouted revision" do
|
39
|
+
expect(notice[:context][:lastCheckout][:revision]).not_to be_empty
|
40
|
+
expect(notice[:context][:lastCheckout][:revision].size).to eq(40)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "attaches last checkouted time" do
|
44
|
+
expect(notice[:context][:lastCheckout][:time]).not_to be_empty
|
45
|
+
expect(notice[:context][:lastCheckout][:time].size).to eq(25)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Airbrake::Filters::GitRepositoryFilter do
|
4
|
+
subject { described_class.new('.') }
|
5
|
+
|
6
|
+
let(:notice) do
|
7
|
+
Airbrake::Notice.new(Airbrake::Config.new, AirbrakeTestError.new)
|
8
|
+
end
|
9
|
+
|
10
|
+
context "when context/repository is defined" do
|
11
|
+
it "doesn't attach anything to context/repository" do
|
12
|
+
notice[:context][:repository] = 'git@github.com:kyrylo/test.git'
|
13
|
+
subject.call(notice)
|
14
|
+
expect(notice[:context][:repository]).to eq('git@github.com:kyrylo/test.git')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when .git directory doesn't exist" do
|
19
|
+
subject { described_class.new('root/dir') }
|
20
|
+
|
21
|
+
it "doesn't attach anything to context/repository" do
|
22
|
+
subject.call(notice)
|
23
|
+
expect(notice[:context][:repository]).to be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when .git directory exists" do
|
28
|
+
it "attaches context/repository" do
|
29
|
+
subject.call(notice)
|
30
|
+
expect(notice[:context][:repository]).to eq(
|
31
|
+
'ssh://git@github.com/airbrake/airbrake-ruby.git'
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/notifier_spec.rb
CHANGED
@@ -95,7 +95,7 @@ RSpec.describe Airbrake::Notifier do
|
|
95
95
|
end
|
96
96
|
|
97
97
|
describe "#notify" do
|
98
|
-
let(:endpoint) { 'https://airbrake.io/api/v3/projects/1/notices' }
|
98
|
+
let(:endpoint) { 'https://api.airbrake.io/api/v3/projects/1/notices' }
|
99
99
|
|
100
100
|
subject { described_class.new(user_params) }
|
101
101
|
|
@@ -129,12 +129,12 @@ RSpec.describe Airbrake::Notifier do
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
context "when a notice is ignored" do
|
132
|
+
context "when a notice is ignored via a filter" do
|
133
133
|
before { subject.add_filter(&:ignore!) }
|
134
134
|
|
135
|
-
it "
|
135
|
+
it "yields the notice" do
|
136
136
|
expect { |b| subject.notify('ex', &b) }
|
137
|
-
.
|
137
|
+
.to yield_with_args(Airbrake::Notice)
|
138
138
|
end
|
139
139
|
|
140
140
|
it "returns a rejected promise" do
|
@@ -143,6 +143,14 @@ RSpec.describe Airbrake::Notifier do
|
|
143
143
|
end
|
144
144
|
end
|
145
145
|
|
146
|
+
context "when a notice is ignored via an inline filter" do
|
147
|
+
before { subject.add_filter { raise AirbrakeTestError } }
|
148
|
+
|
149
|
+
it "doesn't invoke regular filters" do
|
150
|
+
expect { subject.notify('ex', &:ignore!) }.not_to raise_error
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
146
154
|
context "when async sender has workers" do
|
147
155
|
it "sends an exception asynchronously" do
|
148
156
|
expect_any_instance_of(Airbrake::AsyncSender).to receive(:send)
|
@@ -179,7 +187,7 @@ RSpec.describe Airbrake::Notifier do
|
|
179
187
|
end
|
180
188
|
|
181
189
|
describe "#notify_sync" do
|
182
|
-
let(:endpoint) { 'https://airbrake.io/api/v3/projects/1/notices' }
|
190
|
+
let(:endpoint) { 'https://api.airbrake.io/api/v3/projects/1/notices' }
|
183
191
|
|
184
192
|
let(:user_params) do
|
185
193
|
{ project_id: 1, project_key: 'abc', logger: Logger.new('/dev/null') }
|
@@ -221,12 +229,12 @@ RSpec.describe Airbrake::Notifier do
|
|
221
229
|
end
|
222
230
|
end
|
223
231
|
|
224
|
-
context "when a notice is ignored" do
|
232
|
+
context "when a notice is ignored via a filter" do
|
225
233
|
before { subject.add_filter(&:ignore!) }
|
226
234
|
|
227
|
-
it "
|
235
|
+
it "yields the notice" do
|
228
236
|
expect { |b| subject.notify_sync('ex', &b) }
|
229
|
-
.
|
237
|
+
.to yield_with_args(Airbrake::Notice)
|
230
238
|
end
|
231
239
|
|
232
240
|
it "returns an error hash" do
|
@@ -235,6 +243,14 @@ RSpec.describe Airbrake::Notifier do
|
|
235
243
|
end
|
236
244
|
end
|
237
245
|
|
246
|
+
context "when a notice is ignored via an inline filter" do
|
247
|
+
before { subject.add_filter { raise AirbrakeTestError } }
|
248
|
+
|
249
|
+
it "doesn't invoke regular filters" do
|
250
|
+
expect { subject.notify('ex', &:ignore!) }.not_to raise_error
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
238
254
|
context "when the provided environment is ignored" do
|
239
255
|
subject do
|
240
256
|
described_class.new(
|
@@ -393,7 +409,7 @@ RSpec.describe Airbrake::Notifier do
|
|
393
409
|
|
394
410
|
describe "#create_deploy" do
|
395
411
|
it "returns a promise" do
|
396
|
-
stub_request(:post,
|
412
|
+
stub_request(:post, 'https://api.airbrake.io/api/v4/projects/1/deploys')
|
397
413
|
.to_return(status: 201, body: '')
|
398
414
|
expect(subject.create_deploy({})).to be_an(Airbrake::Promise)
|
399
415
|
end
|
@@ -403,7 +419,7 @@ RSpec.describe Airbrake::Notifier do
|
|
403
419
|
expect_any_instance_of(Airbrake::SyncSender).to receive(:send).with(
|
404
420
|
{ environment: 'barenv' },
|
405
421
|
instance_of(Airbrake::Promise),
|
406
|
-
URI('https://airbrake.io/api/v4/projects/1/deploys
|
422
|
+
URI('https://api.airbrake.io/api/v4/projects/1/deploys')
|
407
423
|
)
|
408
424
|
described_class.new(
|
409
425
|
user_params.merge(environment: 'fooenv')
|
@@ -416,7 +432,7 @@ RSpec.describe Airbrake::Notifier do
|
|
416
432
|
expect_any_instance_of(Airbrake::SyncSender).to receive(:send).with(
|
417
433
|
{ environment: 'fooenv' },
|
418
434
|
instance_of(Airbrake::Promise),
|
419
|
-
URI('https://airbrake.io/api/v4/projects/1/deploys
|
435
|
+
URI('https://api.airbrake.io/api/v4/projects/1/deploys')
|
420
436
|
)
|
421
437
|
subject.create_deploy(environment: 'fooenv')
|
422
438
|
end
|
@@ -10,7 +10,7 @@ RSpec.describe Airbrake::Notifier do
|
|
10
10
|
let(:localhost) { 'http://localhost:8080' }
|
11
11
|
|
12
12
|
let(:endpoint) do
|
13
|
-
"https://airbrake.io/api/v3/projects/#{project_id}/notices"
|
13
|
+
"https://api.airbrake.io/api/v3/projects/#{project_id}/notices"
|
14
14
|
end
|
15
15
|
|
16
16
|
let(:airbrake_params) do
|
data/spec/sync_sender_spec.rb
CHANGED
@@ -25,7 +25,7 @@ RSpec.describe Airbrake::SyncSender do
|
|
25
25
|
|
26
26
|
let(:sender) { described_class.new(config) }
|
27
27
|
let(:notice) { Airbrake::Notice.new(config, AirbrakeTestError.new) }
|
28
|
-
let(:endpoint) { 'https://airbrake.io/api/v3/projects/1/notices' }
|
28
|
+
let(:endpoint) { 'https://api.airbrake.io/api/v3/projects/1/notices' }
|
29
29
|
|
30
30
|
before { stub_request(:post, endpoint).to_return(body: '{}') }
|
31
31
|
|
@@ -90,7 +90,7 @@ RSpec.describe Airbrake::SyncSender do
|
|
90
90
|
end
|
91
91
|
|
92
92
|
context "when IP is rate limited" do
|
93
|
-
let(:endpoint) { %r{https://airbrake.io/api/v3/projects/1/notices} }
|
93
|
+
let(:endpoint) { %r{https://api.airbrake.io/api/v3/projects/1/notices} }
|
94
94
|
|
95
95
|
before do
|
96
96
|
stub_request(:post, endpoint).to_return(
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: airbrake-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Airbrake Technologies, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -127,6 +127,8 @@ files:
|
|
127
127
|
- lib/airbrake-ruby/filters/dependency_filter.rb
|
128
128
|
- lib/airbrake-ruby/filters/exception_attributes_filter.rb
|
129
129
|
- lib/airbrake-ruby/filters/gem_root_filter.rb
|
130
|
+
- lib/airbrake-ruby/filters/git_last_checkout_filter.rb
|
131
|
+
- lib/airbrake-ruby/filters/git_repository_filter.rb
|
130
132
|
- lib/airbrake-ruby/filters/git_revision_filter.rb
|
131
133
|
- lib/airbrake-ruby/filters/keys_blacklist.rb
|
132
134
|
- lib/airbrake-ruby/filters/keys_filter.rb
|
@@ -154,6 +156,8 @@ files:
|
|
154
156
|
- spec/filters/dependency_filter_spec.rb
|
155
157
|
- spec/filters/exception_attributes_filter_spec.rb
|
156
158
|
- spec/filters/gem_root_filter_spec.rb
|
159
|
+
- spec/filters/git_last_checkout_filter_spec.rb
|
160
|
+
- spec/filters/git_repository_filter.rb
|
157
161
|
- spec/filters/git_revision_filter_spec.rb
|
158
162
|
- spec/filters/keys_blacklist_spec.rb
|
159
163
|
- spec/filters/keys_whitelist_spec.rb
|
@@ -210,9 +214,11 @@ test_files:
|
|
210
214
|
- spec/filters/thread_filter_spec.rb
|
211
215
|
- spec/filters/dependency_filter_spec.rb
|
212
216
|
- spec/filters/context_filter_spec.rb
|
217
|
+
- spec/filters/git_last_checkout_filter_spec.rb
|
213
218
|
- spec/filters/git_revision_filter_spec.rb
|
214
219
|
- spec/filters/keys_blacklist_spec.rb
|
215
220
|
- spec/filters/gem_root_filter_spec.rb
|
221
|
+
- spec/filters/git_repository_filter.rb
|
216
222
|
- spec/spec_helper.rb
|
217
223
|
- spec/notice_spec.rb
|
218
224
|
- spec/config_spec.rb
|