heroku_hatchet 5.0.2 → 7.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 (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