bigrig 0.1.0 → 0.1.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.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +12 -2
  5. data/lib/bigrig/descriptor.rb +3 -0
  6. data/lib/bigrig/output_parser.rb +46 -7
  7. data/lib/bigrig/version.rb +1 -1
  8. data/spec/bigrig/descriptor_spec.rb +34 -0
  9. data/spec/bigrig/output_parser_spec.rb +22 -0
  10. data/spec/bigrig_spec.rb +9 -1
  11. data/spec/data/adds_volume.json +17 -0
  12. data/spec/data/adds_volumes_from.json +17 -0
  13. data/spec/data/multiple_overrides.json +22 -0
  14. data/spec/support/vcr.rb +7 -2
  15. data/spec/vcr/Bigrig_DestroyAction/_perform/given_json_with_a_single_container/and_the_container_has_exited/should_remove_the_container.yml +46 -46
  16. data/spec/vcr/Bigrig_DestroyAction/_perform/given_json_with_a_single_container/and_the_container_is_running/kills_and_removes_the_container.yml +49 -49
  17. data/spec/vcr/Bigrig_DockerAdapter/_build/builds_the_given_directory.yml +9 -9
  18. data/spec/vcr/Bigrig_DockerAdapter/_build/passes_build_input_to_a_block.yml +4 -4
  19. data/spec/vcr/Bigrig_DockerAdapter/_container_exists_/when_the_container_does_not_exist/is_false.yml +8 -8
  20. data/spec/vcr/Bigrig_DockerAdapter/_container_exists_/when_the_container_exists/is_true.yml +10 -10
  21. data/spec/vcr/Bigrig_DockerAdapter/_image_id_by_tag/when_the_image_does_not_exist/raise_a_ImageNotFoundError.yml +12 -12
  22. data/spec/vcr/Bigrig_DockerAdapter/_image_id_by_tag/when_the_image_exists/returns_the_image_id.yml +12 -12
  23. data/spec/vcr/Bigrig_DockerAdapter/_kill/given_the_container_does_not_exist/should_raise_an_error.yml +8 -8
  24. data/spec/vcr/Bigrig_DockerAdapter/_kill/given_the_container_is_running/should_kill_the_container.yml +22 -22
  25. data/spec/vcr/Bigrig_DockerAdapter/_logs/streams_logs_to_a_block.yml +17 -17
  26. data/spec/vcr/Bigrig_DockerAdapter/_pull/given_a_block_to_capture_output/should_capture_output.yml +4 -4
  27. data/spec/vcr/Bigrig_DockerAdapter/_pull/given_the_repo_does_not_exist/raises_a_RepoNotFoundError.yml +2 -2
  28. data/spec/vcr/Bigrig_DockerAdapter/_pull/given_the_repo_exists/returns_the_image_id.yml +6 -6
  29. data/spec/vcr/Bigrig_DockerAdapter/_push/given_credentials/will_pass_login_and_password.yml +43 -43
  30. data/spec/vcr/Bigrig_DockerAdapter/_push/should_push_the_image.yml +143 -107
  31. data/spec/vcr/Bigrig_DockerAdapter/_remove_container/when_the_container_does_not_exist/raises_a_ContainerNotFoundError.yml +16 -16
  32. data/spec/vcr/Bigrig_DockerAdapter/_remove_container/when_the_container_exists/should_remove_the_container.yml +32 -32
  33. data/spec/vcr/Bigrig_DockerAdapter/_remove_container/when_the_container_is_running/raises_a_ContainerRunningError.yml +10 -10
  34. data/spec/vcr/Bigrig_DockerAdapter/_remove_image/when_the_image_doesnt_exist/raises_an_error.yml +8 -8
  35. data/spec/vcr/Bigrig_DockerAdapter/_remove_image/when_the_image_exists/removes_the_image.yml +27 -27
  36. data/spec/vcr/Bigrig_DockerAdapter/_run/given_an_image_id_that_exists/and_a_name/starts_the_container_with_the_right_name.yml +28 -28
  37. data/spec/vcr/Bigrig_DockerAdapter/_run/given_an_image_id_that_exists/and_a_name_and_env_variables/starts_the_container_with_env_set.yml +28 -28
  38. data/spec/vcr/Bigrig_DockerAdapter/_run/given_an_image_id_that_exists/and_a_name_and_ports/starts_the_container_with_ports_exposed.yml +32 -32
  39. data/spec/vcr/Bigrig_DockerAdapter/_running_/when_the_container_does_not_exist/returns_false.yml +8 -8
  40. data/spec/vcr/Bigrig_DockerAdapter/_running_/when_the_container_is_not_running/returns_false.yml +11 -11
  41. data/spec/vcr/Bigrig_DockerAdapter/_running_/when_the_container_is_running/returns_true.yml +13 -13
  42. data/spec/vcr/Bigrig_DockerAdapter/_tag/should_tag_the_image.yml +30 -83
  43. data/spec/vcr/Bigrig_LogAction/_perform/follows_the_log.yml +17 -17
  44. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_a_path/builds_the_image_before_starting_it.yml +27 -176
  45. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_hosts_by_ip/should_pass_hosts_to_container.yml +41 -41
  46. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_hosts_by_name/should_lookup_ips_for_hosts_with_a_hostname.yml +41 -41
  47. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_links/should_pass_links_to_the_right_container.yml +75 -75
  48. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_multiple_containers/launches_both_containers_in_parallel.yml +52 -52
  49. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_multiple_containers/spins_up_multiple_containers.yml +74 -74
  50. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_one_container/should_spin_up_a_single_container.yml +37 -37
  51. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_one_container/when_a_dead_container_exists/should_remove_existing_containers.yml +39 -39
  52. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_volumes/should_pass_volumes_to_the_right_container.yml +40 -40
  53. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_volumes_from/should_pass_volumes_from_to_the_right_container.yml +75 -75
  54. data/spec/vcr/Bigrig_RunAction/_perform/given_a_file_with_volumes_from/starts_the_dependant_container_last.yml +52 -52
  55. data/spec/vcr/Bigrig_RunAction/_perform/when_activating_profiles_that_do_not_exist/ignores_the_missing_profile.yml +43 -38
  56. data/spec/vcr/Bigrig_RunAction/_perform/with_a_file_with_active_profiles/uses_the_overridden_image.yml +39 -39
  57. data/spec/vcr/bigrig/destroy/spec/data/single_json/kills_the_container.yml +14 -14
  58. data/spec/vcr/bigrig/dev/spec/data/dev_json/activates_the_dev_profile.yml +227 -3
  59. data/spec/vcr/bigrig/dev/spec/data/dev_json/destroys_containers_on_exit.yml +240 -16
  60. data/spec/vcr/bigrig/dev/spec/data/dev_json/starts_the_containers.yml +238 -14
  61. data/spec/vcr/bigrig/dev/spec/data/dev_json/tails_the_logs.yml +227 -0
  62. data/spec/vcr/bigrig/logs/spec/data/log_json/tails_the_logs.yml +17 -17
  63. data/spec/vcr/bigrig/run/spec/data/profiles_json_-p_qa/leaves_existing_env_values_alone.yml +11 -11
  64. data/spec/vcr/bigrig/run/spec/data/profiles_json_-p_qa/overrides_the_env.yml +11 -11
  65. data/spec/vcr/bigrig/run/spec/data/profiles_json_-p_qa/overrides_the_tag.yml +11 -11
  66. data/spec/vcr/bigrig/run/spec/data/single_json/sends_the_name_of_the_container_to_stdout.yml +9 -9
  67. data/spec/vcr/bigrig/run/spec/data/single_json/starts_the_container.yml +13 -13
  68. data/spec/vcr/bigrig/ship/spec/data/ship_json/with_a_version/-c/cleans_the_image_when_its_done.yml +28 -28
  69. data/spec/vcr/bigrig/ship/spec/data/ship_json/with_a_version/builds_and_pushes_the_image.yml +17 -17
  70. data/spec/vcr/bigrig_bin_bigrig_destroy_spec/data/single_json_kills_the_container.yml +21 -21
  71. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_activates_the_dev_profile.yml +109 -107
  72. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_starts_the_containers.yml +108 -108
  73. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_tails_the_logs.yml +118 -118
  74. data/spec/vcr/bigrig_bin_bigrig_logs_spec/data/log_json_tails_the_logs.yml +21 -21
  75. data/spec/vcr/bigrig_bin_bigrig_run_spec/data/profiles_json_-p_qa_leaves_existing_env_values_alone.yml +25 -25
  76. data/spec/vcr/bigrig_bin_bigrig_run_spec/data/profiles_json_-p_qa_overrides_the_env.yml +25 -25
  77. data/spec/vcr/bigrig_bin_bigrig_run_spec/data/profiles_json_-p_qa_overrides_the_tag.yml +24 -173
  78. data/spec/vcr/bigrig_bin_bigrig_run_spec/data/single_json_sends_the_name_of_the_container_to_stdout.yml +25 -25
  79. data/spec/vcr/bigrig_bin_bigrig_run_spec/data/single_json_starts_the_container.yml +25 -25
  80. data/spec/vcr/bigrig_bin_bigrig_ship_spec/data/ship_json_with_a_version_-c_cleans_the_image_when_its_done.yml +121 -85
  81. data/spec/vcr/bigrig_bin_bigrig_ship_spec/data/ship_json_with_a_version_builds_and_pushes_the_image.yml +113 -77
  82. metadata +6 -3
  83. data/spec/vcr/bigrig_bin_bigrig_dev_spec/data/dev_json_destroys_containers_on_exit.yml +0 -1070
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 681ac8a51eebdb90849b5e4d444583f4b651119d
4
- data.tar.gz: d25ebc45f4af29b468231985847e7c1d295348e2
3
+ metadata.gz: a001e90b4c9468158187737587e7927c425d79a7
4
+ data.tar.gz: d1efdce57b29e23ea77d8897cab045ea41be2474
5
5
  SHA512:
6
- metadata.gz: cf7d8a8ad5b9735817c8e2ef4a535a1928afd7314e890693ffc4c883cb9059acf9d83fa510bac8a46b947776e90622ab9cd4e291964be6327a7c5628e4453976
7
- data.tar.gz: 5a6699fd7aa8df839185dcd9f2177c22fcbb6ce349042cb60df644b5167367ce5383384f67ab858246fbc885e226c0f05273e142284d3c1af8a2ae0be2a2b3d8
6
+ metadata.gz: 444a62218b09974941e3e5c6e25e0192e2319c5ee5c095fbf27eb66cb4ca20f07b211daae439c569deee0a0ed2ec628cd7f59febd3276abb73959b490e02bf92
7
+ data.tar.gz: 483ef66f2692664071025f51046988c95380116ddb1cde2e8edd16e7d37b95571404ed79ffea2b88259336f429932f104097330920cc555a7c181b7437f25f7e
data/CHANGELOG.md CHANGED
@@ -21,3 +21,9 @@ Add profiles to most commands
21
21
  0.1.0
22
22
  =====
23
23
  Add `volumes` attriute
24
+
25
+ 0.1.1
26
+ =====
27
+ * Profiles with volumes or volumes_from now augment eachother
28
+ * Profiles are applied based on the order they are defined
29
+ * Enahnce output formatter
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
1
  source 'https://rubygems.org'
2
+
2
3
  gemspec
4
+ gem 'pry-byebug'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bigrig (0.1.0)
4
+ bigrig (0.1.1)
5
5
  colorize (= 0.7.5)
6
6
  docker-api (= 1.20.0)
7
7
  gli (= 2.12.2)
@@ -14,15 +14,21 @@ GEM
14
14
  ast (2.0.0)
15
15
  astrolabe (1.3.0)
16
16
  parser (>= 2.2.0.pre.3, < 3.0)
17
+ byebug (3.5.1)
18
+ columnize (~> 0.8)
19
+ debugger-linecache (~> 1.2)
20
+ slop (~> 3.6)
17
21
  coderay (1.1.0)
18
22
  colorize (0.7.5)
23
+ columnize (0.9.0)
19
24
  crack (0.4.2)
20
25
  safe_yaml (~> 1.0.0)
26
+ debugger-linecache (1.2.0)
21
27
  diff-lcs (1.2.5)
22
28
  docker-api (1.20.0)
23
29
  excon (>= 0.38.0)
24
30
  json
25
- excon (0.44.4)
31
+ excon (0.45.1)
26
32
  gli (2.12.2)
27
33
  json (1.8.2)
28
34
  method_source (0.8.2)
@@ -38,6 +44,9 @@ GEM
38
44
  coderay (~> 1.1.0)
39
45
  method_source (~> 0.8.1)
40
46
  slop (~> 3.4)
47
+ pry-byebug (2.0.0)
48
+ byebug (~> 3.4)
49
+ pry (~> 0.10)
41
50
  rainbow (2.0.0)
42
51
  rake (10.4.2)
43
52
  rspec (3.1.0)
@@ -76,6 +85,7 @@ DEPENDENCIES
76
85
  bigrig!
77
86
  popen4
78
87
  pry
88
+ pry-byebug
79
89
  rake
80
90
  rspec
81
91
  rspec-its
@@ -25,6 +25,8 @@ module Bigrig
25
25
  container = container_map[name] ||= {}
26
26
  if value.is_a? Hash
27
27
  (container[key] ||= {}).merge! value
28
+ elsif %w(volumes volumes_from).include? key
29
+ container[key] = (([container[key]] || []) + [value]).flatten
28
30
  else
29
31
  container[key] = value
30
32
  end
@@ -33,6 +35,7 @@ module Bigrig
33
35
 
34
36
  def self.profiles_for(json, active_profiles)
35
37
  if json['profiles']
38
+ active_profiles = json['profiles'].keys.select { |x| active_profiles.include? x }
36
39
  profiles = active_profiles.map do |profile|
37
40
  [profile, json['profiles'][profile]]
38
41
  end
@@ -1,3 +1,5 @@
1
+ require 'pry-byebug'
2
+
1
3
  module Bigrig
2
4
  class OutputParser
3
5
  def self.parser_proc
@@ -6,25 +8,62 @@ module Bigrig
6
8
 
7
9
  def initialize
8
10
  @last_line = ''
11
+ @buffer = ''
9
12
  end
10
13
 
11
14
  def parse(input)
12
- json = JSON.parse input
13
- if json['errorDetail']
14
- "#{json['errorDetail']['message'].red}\n"
15
- elsif json['stream'] || json['id'].nil?
16
- json['stream'] || "#{json['status']}\n"
17
- else
18
- parse_progress json
15
+ output = documents(input).map do |json|
16
+ if json['errorDetail']
17
+ "#{json['errorDetail']['message'].red}\n"
18
+ elsif json['stream'] || json['id'].nil?
19
+ json['stream'] || "#{json['status']}\n"
20
+ else
21
+ parse_progress json
22
+ end
19
23
  end
24
+ output.join
20
25
  end
21
26
 
22
27
  private
23
28
 
29
+ def documents(str)
30
+ @buffer += str
31
+ documents = []
32
+ begin
33
+ loop do
34
+ documents << JSON.parse(next_document)
35
+ end
36
+ rescue JSON::ParserError # rubocop:disable Lint/HandleExceptions
37
+ end
38
+ documents
39
+ end
40
+
24
41
  def last_line_length
25
42
  @last_line.strip.length
26
43
  end
27
44
 
45
+ # rubocop:disable all
46
+ def next_document
47
+ chars = @buffer.chars
48
+ i = count = 0
49
+ string = false
50
+
51
+ while i < chars.length
52
+ chars[i] == '"' && string = !string
53
+ chars[i] == '\\' && i += 1
54
+ unless string
55
+ chars[i] == '{' && count += 1
56
+ chars[i] == '}' && count -= 1
57
+ end
58
+ count == 0 && chars[0..i].join.strip.length > 0 && break
59
+ i += 1
60
+ end
61
+
62
+ count == 0 && @buffer = (chars.join[i + 1..-1] || '')
63
+ chars.join[0..i]
64
+ end
65
+ # rubocop:enable all
66
+
28
67
  def padding(line)
29
68
  if last_line_length > line.length
30
69
  padding = ' ' * (last_line_length - line.length)
@@ -1,3 +1,3 @@
1
1
  module Bigrig
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -43,6 +43,40 @@ module Bigrig
43
43
  end
44
44
  end
45
45
 
46
+ context 'given a descriptor that adds a volume' do
47
+ let(:file) { 'adds_volume.json' }
48
+ let(:profiles) { ['qa'] }
49
+ let(:volumes) { subject.as_json['adds_volumes']['volumes'] }
50
+
51
+ it 'includes both volumes' do
52
+ expect(volumes).to be_a Array
53
+ expect(volumes).to include '/tmp/volume1'
54
+ expect(volumes).to include '/tmp/volume2'
55
+ end
56
+ end
57
+
58
+ context 'given a descriptor that adds a volumes_from' do
59
+ let(:file) { 'adds_volumes_from.json' }
60
+ let(:profiles) { ['qa'] }
61
+ let(:volumes_from) { subject.as_json['adds_volumes_from']['volumes_from'] }
62
+
63
+ it 'includes both volumes' do
64
+ expect(volumes_from).to be_a Array
65
+ expect(volumes_from).to include 'container1'
66
+ expect(volumes_from).to include 'container2'
67
+ end
68
+ end
69
+
70
+ context 'given a descriptor that overrides the same value in multiple profiles' do
71
+ let(:file) { 'multiple_overrides.json' }
72
+ let(:profiles) { %w(profile2 profile1) }
73
+ let(:tag) { subject.as_json['container']['tag'] }
74
+
75
+ it 'uses the last value in the file' do
76
+ expect(tag).to eq 'profile2'
77
+ end
78
+ end
79
+
46
80
  context 'given a descriptor that adds a container' do
47
81
  let(:file) { 'addscontainer.json' }
48
82
  let(:profiles) { ['new'] }
@@ -9,6 +9,20 @@ module Bigrig
9
9
  let(:mock_io) { double IO }
10
10
  let(:output) { subject }
11
11
 
12
+ context 'when the document comes in multiple chunks' do
13
+ let(:input) { ['{"stream": "val', 'ue"}'] }
14
+ it 'parses the document' do
15
+ expect(output).to eq 'value'
16
+ end
17
+ end
18
+
19
+ context 'when the chunk contains multiple documents' do
20
+ let(:input) { '{"stream": "value1"} {"stream": "value2"}' }
21
+ it 'parses both documents' do
22
+ expect(output).to eq 'value1value2'
23
+ end
24
+ end
25
+
12
26
  context 'with input that has a stream' do
13
27
  let(:input) { '{"stream": "value"}' }
14
28
 
@@ -66,6 +80,14 @@ module Bigrig
66
80
  expect(output).to eq "id: status progress \r"
67
81
  end
68
82
  end
83
+
84
+ context 'given string with tokens' do
85
+ let(:input) { '{"status": "bla bla bla} { \\" bla"}' }
86
+
87
+ it 'ignores the special characters' do
88
+ expect(output).to eq "bla bla bla} { \" bla\n"
89
+ end
90
+ end
69
91
  end
70
92
  end
71
93
  end
data/spec/bigrig_spec.rb CHANGED
@@ -19,6 +19,15 @@ describe 'bigrig' do
19
19
  text.split("\n").each_with_object({}) { |e, o| o.store(*e.split('=')) }
20
20
  end
21
21
 
22
+ before do
23
+ ['dev-test', 'dev-logs'].each do |container|
24
+ begin
25
+ Docker::Container.get(container).kill.delete
26
+ rescue Docker::Error::NotFoundError # rubocop:disable Lint/HandleExceptions
27
+ end
28
+ end
29
+ end
30
+
22
31
  it 'starts the containers', :vcr do
23
32
  command = %(spec/support/bigrig_vcr "#{casette_name}" #{args.join ' '})
24
33
  pid = Open4.popen4(command).first
@@ -37,7 +46,6 @@ describe 'bigrig' do
37
46
  it 'destroys containers on exit', :vcr do
38
47
  command = %(spec/support/bigrig_vcr "#{casette_name}" #{args.join ' '})
39
48
  pid = Open4.popen4(command).first
40
- sleep 2
41
49
  Process.kill :SIGINT, pid
42
50
  Process.wait pid
43
51
  begin
@@ -0,0 +1,17 @@
1
+ {
2
+ "containers": {
3
+ "adds_volumes": {
4
+ "repo": "hawknewton/true",
5
+ "tag": "0.0.1",
6
+ "volumes": "/tmp/volume1"
7
+ }
8
+ },
9
+
10
+ "profiles": {
11
+ "qa": {
12
+ "adds_volumes": {
13
+ "volumes": "/tmp/volume2"
14
+ }
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "containers": {
3
+ "adds_volumes_from": {
4
+ "repo": "hawknewton/true",
5
+ "tag": "0.0.1",
6
+ "volumes_from": "container1"
7
+ }
8
+ },
9
+
10
+ "profiles": {
11
+ "qa": {
12
+ "adds_volumes_from": {
13
+ "volumes_from": "container2"
14
+ }
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "containers": {
3
+ "container": {
4
+ "repo": "hawknewton/true",
5
+ "tag": "0.0.1"
6
+ }
7
+ },
8
+
9
+ "profiles": {
10
+ "profile1": {
11
+ "container": {
12
+ "tag": "profile1"
13
+ }
14
+ },
15
+
16
+ "profile2": {
17
+ "container": {
18
+ "tag": "profile2"
19
+ }
20
+ }
21
+ }
22
+ }
data/spec/support/vcr.rb CHANGED
@@ -3,12 +3,17 @@ require 'webmock'
3
3
  require 'docker'
4
4
 
5
5
  VCR.configure do |c|
6
+ docker_host = URI.parse(Docker.url).host
6
7
  c.allow_http_connections_when_no_cassette = false
7
- c.filter_sensitive_data('<DOCKER_HOST>') { Docker.url.sub(/tcp\:/, 'https:') }
8
- c.filter_sensitive_data('<DOCKER_HTTP>') { "http:#{Docker.url.split(':')[1]}:4567" }
9
8
  c.filter_sensitive_data('<USERNAME>') { ENV['DOCKER_API_USER'] }
10
9
  c.filter_sensitive_data('<PASSWORD>') { ENV['DOCKER_API_PASS'] }
11
10
  c.filter_sensitive_data('<EMAIL>') { ENV['DOCKER_API_EMAIL'] }
11
+
12
+ c.define_cassette_placeholder('<ENCODED_REPO_URL>') { "#{docker_host}%3A5000" }
13
+ c.define_cassette_placeholder('<REPO_URL>') { "#{docker_host}:5000" }
14
+ c.define_cassette_placeholder('<TEST_URL>') { "http://#{docker_host}:4568" }
15
+ c.define_cassette_placeholder('<DOCKER_HOST>') { Docker.url.sub(/tcp\:/, 'https:') }
16
+ c.define_cassette_placeholder('<DOCKER_HTTP>') { "http:#{Docker.url.split(':')[1]}:4567" }
12
17
  c.hook_into :excon, :webmock
13
18
  c.cassette_library_dir = File.join(File.dirname(__FILE__), '..', 'vcr')
14
19
  defined?(RSpec) && c.configure_rspec_metadata!