heroku_hatchet 5.0.2 → 7.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +21 -1
  3. data/.gitignore +2 -0
  4. data/CHANGELOG.md +36 -1
  5. data/README.md +790 -164
  6. data/bin/hatchet +19 -7
  7. data/etc/ci_setup.rb +16 -12
  8. data/etc/setup_heroku.sh +0 -2
  9. data/hatchet.gemspec +4 -6
  10. data/hatchet.json +6 -2
  11. data/hatchet.lock +12 -8
  12. data/lib/hatchet.rb +1 -2
  13. data/lib/hatchet/api_rate_limit.rb +13 -24
  14. data/lib/hatchet/app.rb +150 -41
  15. data/lib/hatchet/config.rb +1 -1
  16. data/lib/hatchet/git_app.rb +28 -1
  17. data/lib/hatchet/reaper.rb +159 -56
  18. data/lib/hatchet/reaper/app_age.rb +49 -0
  19. data/lib/hatchet/reaper/reaper_throttle.rb +55 -0
  20. data/lib/hatchet/shell_throttle.rb +71 -0
  21. data/lib/hatchet/test_run.rb +16 -9
  22. data/lib/hatchet/version.rb +1 -1
  23. data/{test → repo_fixtures}/different-folder-for-checked-in-repos/default_ruby/Gemfile +0 -0
  24. data/spec/hatchet/allow_failure_git_spec.rb +55 -0
  25. data/spec/hatchet/app_spec.rb +226 -0
  26. data/spec/hatchet/ci_spec.rb +67 -0
  27. data/spec/hatchet/config_spec.rb +34 -0
  28. data/spec/hatchet/edit_repo_spec.rb +17 -0
  29. data/spec/hatchet/git_spec.rb +9 -0
  30. data/spec/hatchet/heroku_api_spec.rb +30 -0
  31. data/spec/hatchet/local_repo_spec.rb +26 -0
  32. data/spec/hatchet/lock_spec.rb +81 -0
  33. data/spec/spec_helper.rb +25 -0
  34. data/spec/unit/reaper_spec.rb +169 -0
  35. data/spec/unit/shell_throttle.rb +28 -0
  36. metadata +43 -87
  37. data/.travis.yml +0 -16
  38. data/test/fixtures/buildpacks/null-buildpack/bin/compile +0 -4
  39. data/test/fixtures/buildpacks/null-buildpack/bin/detect +0 -5
  40. data/test/fixtures/buildpacks/null-buildpack/bin/release +0 -3
  41. data/test/fixtures/buildpacks/null-buildpack/hatchet.json +0 -4
  42. data/test/fixtures/buildpacks/null-buildpack/readme.md +0 -41
  43. data/test/hatchet/allow_failure_git_test.rb +0 -16
  44. data/test/hatchet/app_test.rb +0 -96
  45. data/test/hatchet/ci_four_test.rb +0 -19
  46. data/test/hatchet/ci_test.rb +0 -11
  47. data/test/hatchet/ci_three_test.rb +0 -20
  48. data/test/hatchet/ci_too_test.rb +0 -19
  49. data/test/hatchet/config_test.rb +0 -51
  50. data/test/hatchet/edit_repo_test.rb +0 -20
  51. data/test/hatchet/git_test.rb +0 -16
  52. data/test/hatchet/heroku_api_test.rb +0 -30
  53. data/test/hatchet/labs_test.rb +0 -20
  54. data/test/hatchet/local_repo_test.rb +0 -26
  55. data/test/hatchet/lock_test.rb +0 -9
  56. data/test/hatchet/multi_cmd_runner_test.rb +0 -30
  57. data/test/test_helper.rb +0 -28
@@ -0,0 +1,9 @@
1
+ require "spec_helper"
2
+
3
+ describe "GitAppTest" do
4
+ it "can deploy git app" do
5
+ Hatchet::GitApp.new("rails5_ruby_schema_format").deploy do |app|
6
+ expect(app.run("ruby -v")).to match("2.6.6")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,30 @@
1
+ require("spec_helper")
2
+ describe "HerokuApiTest" do
3
+ it "config vars" do
4
+ begin
5
+ runner = Hatchet::Runner.new("no_lockfile").setup!
6
+ actual = runner.get_config
7
+ actual.delete("BUILDPACK_URL")
8
+ expect(actual).to eq({})
9
+
10
+ runner.set_config("foo" => "bar")
11
+
12
+ actual = runner.get_config
13
+ actual.delete("BUILDPACK_URL")
14
+ expect(actual).to eq({ "foo" => "bar" })
15
+ ensure
16
+ runner.teardown! if runner
17
+ end
18
+ end
19
+
20
+ it "config vars in init" do
21
+ begin
22
+ runner = Hatchet::Runner.new("no_lockfile", config: { foo: "bar" }).setup!
23
+ actual = runner.get_config
24
+
25
+ expect(actual).to eq({ "foo" => "bar" })
26
+ ensure
27
+ runner.teardown! if runner
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ require("spec_helper")
2
+ describe "LocalRepoTest" do
3
+ it "in directory fork" do
4
+ env_name = SecureRandom.hex
5
+ ENV[env_name] = env_name
6
+ Hatchet::App.new("default_ruby").in_directory_fork do
7
+ ENV.delete(env_name) # Does not affect parent env
8
+ expect(ENV[env_name]).to be_nil
9
+ end
10
+
11
+ expect(ENV[env_name]).to eq(env_name)
12
+ end
13
+
14
+ it "repos checked into git" do
15
+ begin
16
+ app = Hatchet::App.new("repo_fixtures/different-folder-for-checked-in-repos/default_ruby")
17
+ app.in_directory do
18
+ expect(Dir.exist?(".git")).to eq(false)
19
+ app.setup!
20
+ expect(Dir.exist?(".git")).to eq(true)
21
+ end
22
+ ensure
23
+ app.teardown! if app
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,81 @@
1
+ require "spec_helper"
2
+ require 'yaml'
3
+
4
+ describe "LockTest" do
5
+ before(:all) do
6
+ puts(`bundle exec hatchet lock`)
7
+ end
8
+
9
+ it "app with failure can be locked to prior commit" do
10
+ Hatchet::GitApp.new("lock_fail").deploy do |app|
11
+ expect(app.deployed?).to be_truthy
12
+ end
13
+ end
14
+
15
+ it "app with failure can be locked to master" do
16
+ lock = YAML.load_file("hatchet.lock")
17
+ name, branch = lock.select { |k, v| k.end_with?("lock_fail_master") }.first
18
+
19
+ expect(name).to eq("repo_fixtures/repos/lock/lock_fail_master")
20
+ expect(branch).to eq("master")
21
+ end
22
+
23
+ it "app with failure can be locked to main" do
24
+ lock = YAML.load_file("hatchet.lock")
25
+ name, branch = lock.select { |k, v| k.end_with?("lock_fail_main") }.first
26
+
27
+ expect(name).to eq("repo_fixtures/repos/lock/lock_fail_main")
28
+ expect(branch).to eq("main")
29
+ end
30
+ end
31
+
32
+ describe "isolated lock tests" do
33
+ it "works when there's no hatchet.lock" do
34
+ Dir.mktmpdir do |dir|
35
+ dir = Pathname.new(dir)
36
+
37
+ dir.join("hatchet.json").open("w+") do |f|
38
+ f.puts %Q{{ "foo": ["sharpstone/lock_fail_main_default_is_master"] }}
39
+ end
40
+
41
+ output = `cd #{dir} && hatchet lock 2>&1`
42
+
43
+ raise "Expected cmd `hatchet lock` to succeed, but it did not: #{output}" unless $?.success?
44
+ expect(output).to include("locking")
45
+
46
+ lockfile_contents = dir.join('hatchet.lock').read
47
+ expect(lockfile_contents).to include("repos/foo/lock_fail_main_default_is_master")
48
+ end
49
+ end
50
+
51
+ it "works when a project is locked to main but the default branch is master" do
52
+ Dir.mktmpdir do |dir|
53
+ dir = Pathname.new(dir)
54
+
55
+ dir.join("hatchet.json").open("w+") do |f|
56
+ f.puts %Q{{ "foo": ["sharpstone/lock_fail_main_default_is_master"] }}
57
+ end
58
+
59
+ dir.join("hatchet.lock").open("w+") do |f|
60
+ f.puts <<~EOM
61
+ ---
62
+ - - "./repos/foo/lock_fail_main_default_is_master"
63
+ - main
64
+ EOM
65
+ end
66
+
67
+ output = `cd #{dir} && hatchet install 2>&1`
68
+
69
+ raise "Expected cmd `hatchet install` to succeed, but it did not:\n#{output}" unless $?.success?
70
+ expect(output).to include("Installing")
71
+
72
+ lockfile_contents = dir.join('hatchet.lock').read
73
+ contents = YAML.safe_load(lockfile_contents).to_h
74
+ expect(contents).to eq({"./repos/foo/lock_fail_main_default_is_master" => "main"})
75
+
76
+ contents.each do |repo_dir, commit_or_branch|
77
+ expect(`cd #{dir.join(repo_dir)} && git describe --contains --all HEAD`).to match("main")
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,25 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'hatchet'
3
+ require 'rspec/retry'
4
+ require "bundler/setup"
5
+
6
+ RSpec.configure do |config|
7
+ # Enable flags like --only-failures and --next-failure
8
+ config.example_status_persistence_file_path = ".rspec_status"
9
+ config.verbose_retry = true # show retry status in spec process
10
+ config.default_retry_count = 2 if ENV['IS_RUNNING_ON_CI'] # retry all tests that fail again
11
+
12
+ config.expect_with :rspec do |c|
13
+ c.syntax = :expect
14
+ end
15
+ end
16
+
17
+ ENV['HATCHET_BUILDPACK_BRANCH'] = "master"
18
+
19
+ require 'parallel_tests/test/runtime_logger' if ENV['RECORD_RUNTIME']
20
+
21
+ def run!(cmd)
22
+ out = `#{cmd}`
23
+ raise "Error running #{cmd}, output: #{out}" unless $?.success?
24
+ out
25
+ end
@@ -0,0 +1,169 @@
1
+ require "spec_helper"
2
+
3
+ describe "Reaper" do
4
+ it "destroy all" do
5
+ reaper = Hatchet::Reaper.new(api_rate_limit: Object.new, hatchet_app_limit: 1, io: StringIO.new)
6
+
7
+ def reaper.get_heroku_apps
8
+ @mock_apps ||= [
9
+ {"name" => "hatchet-t-unfinished", "id" => 2, "maintenance" => false, "created_at" => Time.now.to_s},
10
+ {"name" => "hatchet-t-foo", "id" => 1, "maintenance" => true, "created_at" => Time.now.to_s}
11
+ ]
12
+ end
13
+ def reaper.destroy_with_log(*args); @destroy_with_log_count ||= 0; @destroy_with_log_count += 1; end
14
+
15
+ reaper.destroy_all
16
+
17
+ expect(reaper.instance_variable_get("@destroy_with_log_count")).to eq(1)
18
+ end
19
+
20
+ describe "cycle" do
21
+ it "does not delete anything if under the limit" do
22
+ reaper = Hatchet::Reaper.new(api_rate_limit: Object.new, hatchet_app_limit: 1, io: StringIO.new)
23
+
24
+ def reaper.get_heroku_apps
25
+ @called_get_heroku_apps = true
26
+
27
+ @mock_apps ||= [{"name" => "hatchet-t-foo", "id" => 1, "maintenance" => true, "created_at" => Time.now.to_s}]
28
+ end
29
+ def reaper.check_get_heroku_apps_called; @called_get_heroku_apps ; end
30
+ def reaper.reap_once; raise "should not be called"; end
31
+
32
+ reaper.cycle
33
+
34
+ expect(reaper.check_get_heroku_apps_called).to be_truthy
35
+ end
36
+
37
+ it "deletes a maintenance mode app on error" do
38
+ reaper = Hatchet::Reaper.new(api_rate_limit: Object.new, hatchet_app_limit: 1, io: StringIO.new)
39
+
40
+ def reaper.get_heroku_apps
41
+ @mock_apps ||= [
42
+ {"name" => "hatchet-t-unfinished", "id" => 2, "maintenance" => false, "created_at" => Time.now.to_s},
43
+ {"name" => "hatchet-t-foo", "id" => 1, "maintenance" => true, "created_at" => Time.now.to_s}
44
+ ]
45
+ end
46
+ def reaper.destroy_with_log(name: , id: )
47
+ @reaper_destroy_called_with = {"name" => name, "id" => id}
48
+ end
49
+ def reaper.destroy_called_with; @reaper_destroy_called_with; end
50
+
51
+ reaper.cycle(app_exception_message: true)
52
+
53
+ expect(reaper.destroy_called_with).to eq({"name" => "hatchet-t-foo", "id" => 1})
54
+ end
55
+
56
+ it "deletes maintenance mode app when over limit" do
57
+ reaper = Hatchet::Reaper.new(api_rate_limit: Object.new, hatchet_app_limit: 0, io: StringIO.new)
58
+
59
+ def reaper.get_heroku_apps
60
+ @mock_apps ||= [{"name" => "hatchet-t-foo", "id" => 1, "maintenance" => true, "created_at" => Time.now.to_s}]
61
+ end
62
+ def reaper.destroy_with_log(name: , id: )
63
+ @reaper_destroy_called_with = {"name" => name, "id" => id}
64
+ end
65
+ def reaper.destroy_called_with; @reaper_destroy_called_with; end
66
+
67
+ reaper.cycle
68
+
69
+ expect(reaper.destroy_called_with).to eq({"name" => "hatchet-t-foo", "id" => 1})
70
+ end
71
+
72
+ it "deletes an old app that is past TLL" do
73
+ reaper = Hatchet::Reaper.new(api_rate_limit: Object.new, hatchet_app_limit: 0, io: StringIO.new)
74
+
75
+ def reaper.get_heroku_apps
76
+ two_days_ago = DateTime.now.new_offset(0) - 2
77
+ @mock_apps ||= [{"name" => "hatchet-t-foo", "id" => 1, "maintenance" => false, "created_at" => two_days_ago.to_s }]
78
+ end
79
+ def reaper.destroy_with_log(name: , id: )
80
+ @reaper_destroy_called_with = {"name" => name, "id" => id}
81
+ end
82
+ def reaper.destroy_called_with; @reaper_destroy_called_with; end
83
+
84
+ reaper.cycle
85
+
86
+ expect(reaper.destroy_called_with).to eq({"name" => "hatchet-t-foo", "id" => 1})
87
+ end
88
+
89
+ it "sleeps, refreshes app list, and tries again when an old app is not past TTL" do
90
+ warning = StringIO.new
91
+ reaper = Hatchet::Reaper.new(api_rate_limit: Object.new, hatchet_app_limit: 1, initial_sleep: 0, io: warning)
92
+
93
+ def reaper.get_heroku_apps
94
+ now = DateTime.now.new_offset(0)
95
+ @mock_apps ||= [{"name" => "hatchet-t-foo", "id" => 1, "maintenance" => false, "created_at" => now.to_s }]
96
+ end
97
+ def reaper.destroy_with_log(name: , id: )
98
+ @reaper_destroy_called_with = {"name" => name, "id" => id}
99
+ end
100
+ def reaper.destroy_called_with; @reaper_destroy_called_with; end
101
+ def reaper.sleep(val)
102
+ @_slept_for = val
103
+ end
104
+
105
+ def reaper.get_slept_for_val; @_slept_for; end
106
+
107
+ reaper.cycle(app_exception_message: true)
108
+
109
+ expect(reaper.get_slept_for_val).to eq(0)
110
+ expect(reaper.destroy_called_with).to eq(nil)
111
+
112
+ expect(warning.string).to match("WARNING")
113
+ expect(warning.string).to match("total_app_count: 1, hatchet_app_count: 1/#{Hatchet::Reaper::HATCHET_APP_LIMIT}, finished: 0, unfinished: 1")
114
+ end
115
+ end
116
+
117
+ describe "app age" do
118
+ it "calculates young apps" do
119
+ time_now = DateTime.parse("2020-07-28T14:40:00Z")
120
+ age = Hatchet::Reaper::AppAge.new(created_at: time_now, time_now: time_now, ttl_minutes: 1)
121
+ expect(age.in_minutes).to eq(0.0)
122
+ expect(age.too_young_to_die?).to be_truthy
123
+ expect(age.can_delete?).to be_falsey
124
+ expect(age.sleep_for_ttl).to eq(60)
125
+ end
126
+
127
+ it "calculates old apps" do
128
+ time_now = DateTime.parse("2020-07-28T14:40:00Z")
129
+ created_at = time_now - 2
130
+ age = Hatchet::Reaper::AppAge.new(created_at: created_at, time_now: time_now, ttl_minutes: 1)
131
+ expect(age.in_minutes).to eq(2880.0)
132
+ expect(age.too_young_to_die?).to be_falsey
133
+ expect(age.can_delete?).to be_truthy
134
+ expect(age.sleep_for_ttl).to eq(0)
135
+ end
136
+ end
137
+
138
+ describe "reaper throttle" do
139
+ it "increments and decrements based on min_sleep" do
140
+ reaper_throttle = Hatchet::Reaper::ReaperThrottle.new(initial_sleep: 2)
141
+ reaper_throttle.call(max_sleep: 5) do |sleep_for|
142
+ expect(sleep_for).to eq(2)
143
+ end
144
+ reaper_throttle.call(max_sleep: 5) do |sleep_for|
145
+ expect(sleep_for).to eq(4)
146
+ end
147
+ reaper_throttle.call(max_sleep: 5) do |sleep_for|
148
+ expect(sleep_for).to eq(5)
149
+ end
150
+ # The throttle is now reset since it hit the min_sleep value
151
+
152
+ reaper_throttle.call(max_sleep: 5) do |sleep_for|
153
+ expect(sleep_for).to eq(2)
154
+ end
155
+ end
156
+ end
157
+
158
+ it "over limit" do
159
+ reaper = Hatchet::Reaper.new(api_rate_limit: -> (){}, io: StringIO.new)
160
+ def reaper.hatchet_app_count; Hatchet::Reaper::HATCHET_APP_LIMIT + 1; end
161
+
162
+ expect(reaper.over_limit?).to be_truthy
163
+
164
+ reaper = Hatchet::Reaper.new(api_rate_limit: -> (){}, io: StringIO.new)
165
+ def reaper.hatchet_app_count; Hatchet::Reaper::HATCHET_APP_LIMIT - 1; end
166
+
167
+ expect(reaper.over_limit?).to be_falsey
168
+ end
169
+ end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
2
+
3
+ describe "ShellThrottle" do
4
+ it "throttles when throw is called" do
5
+ platform_api = Hatchet::Runner.new("default_ruby").platform_api
6
+
7
+ @count = 0
8
+ Hatchet::ShellThrottle.new(platform_api: platform_api).call do
9
+ @count += 1
10
+ if @count >= 2
11
+ # No throttle
12
+ else
13
+ throw(:throttle)
14
+ end
15
+ end
16
+ expect(@count).to eq(2)
17
+ end
18
+
19
+ it "does not throttle when throw is NOT called" do
20
+ platform_api = Hatchet::Runner.new("default_ruby").platform_api
21
+
22
+ @count = 0
23
+ Hatchet::ShellThrottle.new(platform_api: platform_api).call do
24
+ @count += 1
25
+ end
26
+ expect(@count).to eq(1)
27
+ end
28
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroku_hatchet
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.2
4
+ version: 7.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Schneeman
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-24 00:00:00.000000000 Z
11
+ date: 2020-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: platform-api
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '2'
19
+ version: '3'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '2'
26
+ version: '3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rrrretry
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -66,20 +66,6 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: repl_runner
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 0.0.3
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 0.0.3
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: threaded
85
71
  requirement: !ruby/object:Gem::Requirement
@@ -95,33 +81,19 @@ dependencies:
95
81
  - !ruby/object:Gem::Version
96
82
  version: '0'
97
83
  - !ruby/object:Gem::Dependency
98
- name: minitest-retry
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: 0.1.9
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: 0.1.9
111
- - !ruby/object:Gem::Dependency
112
- name: minitest
84
+ name: rspec
113
85
  requirement: !ruby/object:Gem::Requirement
114
86
  requirements:
115
87
  - - ">="
116
88
  - !ruby/object:Gem::Version
117
- version: '5.1'
89
+ version: '0'
118
90
  type: :development
119
91
  prerelease: false
120
92
  version_requirements: !ruby/object:Gem::Requirement
121
93
  requirements:
122
94
  - - ">="
123
95
  - !ruby/object:Gem::Version
124
- version: '5.1'
96
+ version: '0'
125
97
  - !ruby/object:Gem::Dependency
126
98
  name: rake
127
99
  requirement: !ruby/object:Gem::Requirement
@@ -151,19 +123,19 @@ dependencies:
151
123
  - !ruby/object:Gem::Version
152
124
  version: '1'
153
125
  - !ruby/object:Gem::Dependency
154
- name: parallel_tests
126
+ name: parallel_split_test
155
127
  requirement: !ruby/object:Gem::Requirement
156
128
  requirements:
157
129
  - - ">="
158
130
  - !ruby/object:Gem::Version
159
- version: '2'
131
+ version: '0'
160
132
  type: :development
161
133
  prerelease: false
162
134
  version_requirements: !ruby/object:Gem::Requirement
163
135
  requirements:
164
136
  - - ">="
165
137
  - !ruby/object:Gem::Version
166
- version: '2'
138
+ version: '0'
167
139
  - !ruby/object:Gem::Dependency
168
140
  name: travis
169
141
  requirement: !ruby/object:Gem::Requirement
@@ -179,7 +151,7 @@ dependencies:
179
151
  - !ruby/object:Gem::Version
180
152
  version: '1'
181
153
  - !ruby/object:Gem::Dependency
182
- name: m
154
+ name: rspec-retry
183
155
  requirement: !ruby/object:Gem::Requirement
184
156
  requirements:
185
157
  - - ">="
@@ -203,7 +175,6 @@ files:
203
175
  - ".circleci/config.yml"
204
176
  - ".github/workflows/check_changelog.yml"
205
177
  - ".gitignore"
206
- - ".travis.yml"
207
178
  - CHANGELOG.md
208
179
  - Gemfile
209
180
  - LICENSE.txt
@@ -222,37 +193,32 @@ files:
222
193
  - lib/hatchet/config.rb
223
194
  - lib/hatchet/git_app.rb
224
195
  - lib/hatchet/reaper.rb
196
+ - lib/hatchet/reaper/app_age.rb
197
+ - lib/hatchet/reaper/reaper_throttle.rb
198
+ - lib/hatchet/shell_throttle.rb
225
199
  - lib/hatchet/tasks.rb
226
200
  - lib/hatchet/test_run.rb
227
201
  - lib/hatchet/version.rb
228
- - test/different-folder-for-checked-in-repos/default_ruby/Gemfile
229
- - test/different-folder-for-checked-in-repos/default_ruby/Gemfile.lock
230
- - test/fixtures/buildpacks/null-buildpack/bin/compile
231
- - test/fixtures/buildpacks/null-buildpack/bin/detect
232
- - test/fixtures/buildpacks/null-buildpack/bin/release
233
- - test/fixtures/buildpacks/null-buildpack/hatchet.json
234
- - test/fixtures/buildpacks/null-buildpack/readme.md
235
- - test/hatchet/allow_failure_git_test.rb
236
- - test/hatchet/app_test.rb
237
- - test/hatchet/ci_four_test.rb
238
- - test/hatchet/ci_test.rb
239
- - test/hatchet/ci_three_test.rb
240
- - test/hatchet/ci_too_test.rb
241
- - test/hatchet/config_test.rb
242
- - test/hatchet/edit_repo_test.rb
243
- - test/hatchet/git_test.rb
244
- - test/hatchet/heroku_api_test.rb
245
- - test/hatchet/labs_test.rb
246
- - test/hatchet/local_repo_test.rb
247
- - test/hatchet/lock_test.rb
248
- - test/hatchet/multi_cmd_runner_test.rb
249
- - test/test_helper.rb
202
+ - repo_fixtures/different-folder-for-checked-in-repos/default_ruby/Gemfile
203
+ - repo_fixtures/different-folder-for-checked-in-repos/default_ruby/Gemfile.lock
204
+ - spec/hatchet/allow_failure_git_spec.rb
205
+ - spec/hatchet/app_spec.rb
206
+ - spec/hatchet/ci_spec.rb
207
+ - spec/hatchet/config_spec.rb
208
+ - spec/hatchet/edit_repo_spec.rb
209
+ - spec/hatchet/git_spec.rb
210
+ - spec/hatchet/heroku_api_spec.rb
211
+ - spec/hatchet/local_repo_spec.rb
212
+ - spec/hatchet/lock_spec.rb
213
+ - spec/spec_helper.rb
214
+ - spec/unit/reaper_spec.rb
215
+ - spec/unit/shell_throttle.rb
250
216
  - tmp/parallel_runtime_test.log
251
217
  homepage: https://github.com/heroku/hatchet
252
218
  licenses:
253
219
  - MIT
254
220
  metadata: {}
255
- post_install_message:
221
+ post_install_message:
256
222
  rdoc_options: []
257
223
  require_paths:
258
224
  - lib
@@ -268,29 +234,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
268
234
  version: '0'
269
235
  requirements: []
270
236
  rubygems_version: 3.1.2
271
- signing_key:
237
+ signing_key:
272
238
  specification_version: 4
273
239
  summary: Hatchet is a an integration testing library for developing Heroku buildpacks.
274
240
  test_files:
275
- - test/different-folder-for-checked-in-repos/default_ruby/Gemfile
276
- - test/different-folder-for-checked-in-repos/default_ruby/Gemfile.lock
277
- - test/fixtures/buildpacks/null-buildpack/bin/compile
278
- - test/fixtures/buildpacks/null-buildpack/bin/detect
279
- - test/fixtures/buildpacks/null-buildpack/bin/release
280
- - test/fixtures/buildpacks/null-buildpack/hatchet.json
281
- - test/fixtures/buildpacks/null-buildpack/readme.md
282
- - test/hatchet/allow_failure_git_test.rb
283
- - test/hatchet/app_test.rb
284
- - test/hatchet/ci_four_test.rb
285
- - test/hatchet/ci_test.rb
286
- - test/hatchet/ci_three_test.rb
287
- - test/hatchet/ci_too_test.rb
288
- - test/hatchet/config_test.rb
289
- - test/hatchet/edit_repo_test.rb
290
- - test/hatchet/git_test.rb
291
- - test/hatchet/heroku_api_test.rb
292
- - test/hatchet/labs_test.rb
293
- - test/hatchet/local_repo_test.rb
294
- - test/hatchet/lock_test.rb
295
- - test/hatchet/multi_cmd_runner_test.rb
296
- - test/test_helper.rb
241
+ - spec/hatchet/allow_failure_git_spec.rb
242
+ - spec/hatchet/app_spec.rb
243
+ - spec/hatchet/ci_spec.rb
244
+ - spec/hatchet/config_spec.rb
245
+ - spec/hatchet/edit_repo_spec.rb
246
+ - spec/hatchet/git_spec.rb
247
+ - spec/hatchet/heroku_api_spec.rb
248
+ - spec/hatchet/local_repo_spec.rb
249
+ - spec/hatchet/lock_spec.rb
250
+ - spec/spec_helper.rb
251
+ - spec/unit/reaper_spec.rb
252
+ - spec/unit/shell_throttle.rb