crazy-yard 3.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +19 -0
  3. data/README.md +438 -0
  4. data/bin/ey +9 -0
  5. data/lib/engineyard.rb +9 -0
  6. data/lib/engineyard/cli.rb +816 -0
  7. data/lib/engineyard/cli/api.rb +98 -0
  8. data/lib/engineyard/cli/recipes.rb +129 -0
  9. data/lib/engineyard/cli/ui.rb +275 -0
  10. data/lib/engineyard/cli/web.rb +85 -0
  11. data/lib/engineyard/config.rb +158 -0
  12. data/lib/engineyard/deploy_config.rb +65 -0
  13. data/lib/engineyard/deploy_config/ref.rb +56 -0
  14. data/lib/engineyard/error.rb +82 -0
  15. data/lib/engineyard/eyrc.rb +59 -0
  16. data/lib/engineyard/repo.rb +105 -0
  17. data/lib/engineyard/serverside_runner.rb +159 -0
  18. data/lib/engineyard/templates.rb +6 -0
  19. data/lib/engineyard/templates/ey.yml.erb +196 -0
  20. data/lib/engineyard/templates/ey_yml.rb +119 -0
  21. data/lib/engineyard/thor.rb +215 -0
  22. data/lib/engineyard/version.rb +4 -0
  23. data/lib/vendor/thor/Gemfile +15 -0
  24. data/lib/vendor/thor/LICENSE.md +20 -0
  25. data/lib/vendor/thor/README.md +35 -0
  26. data/lib/vendor/thor/lib/thor.rb +473 -0
  27. data/lib/vendor/thor/lib/thor/actions.rb +318 -0
  28. data/lib/vendor/thor/lib/thor/actions/create_file.rb +105 -0
  29. data/lib/vendor/thor/lib/thor/actions/create_link.rb +60 -0
  30. data/lib/vendor/thor/lib/thor/actions/directory.rb +119 -0
  31. data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +137 -0
  32. data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +314 -0
  33. data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +109 -0
  34. data/lib/vendor/thor/lib/thor/base.rb +652 -0
  35. data/lib/vendor/thor/lib/thor/command.rb +136 -0
  36. data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +80 -0
  37. data/lib/vendor/thor/lib/thor/core_ext/io_binary_read.rb +12 -0
  38. data/lib/vendor/thor/lib/thor/core_ext/ordered_hash.rb +100 -0
  39. data/lib/vendor/thor/lib/thor/error.rb +28 -0
  40. data/lib/vendor/thor/lib/thor/group.rb +282 -0
  41. data/lib/vendor/thor/lib/thor/invocation.rb +172 -0
  42. data/lib/vendor/thor/lib/thor/parser.rb +4 -0
  43. data/lib/vendor/thor/lib/thor/parser/argument.rb +74 -0
  44. data/lib/vendor/thor/lib/thor/parser/arguments.rb +171 -0
  45. data/lib/vendor/thor/lib/thor/parser/option.rb +121 -0
  46. data/lib/vendor/thor/lib/thor/parser/options.rb +218 -0
  47. data/lib/vendor/thor/lib/thor/rake_compat.rb +72 -0
  48. data/lib/vendor/thor/lib/thor/runner.rb +322 -0
  49. data/lib/vendor/thor/lib/thor/shell.rb +88 -0
  50. data/lib/vendor/thor/lib/thor/shell/basic.rb +393 -0
  51. data/lib/vendor/thor/lib/thor/shell/color.rb +148 -0
  52. data/lib/vendor/thor/lib/thor/shell/html.rb +127 -0
  53. data/lib/vendor/thor/lib/thor/util.rb +270 -0
  54. data/lib/vendor/thor/lib/thor/version.rb +3 -0
  55. data/lib/vendor/thor/thor.gemspec +24 -0
  56. data/spec/engineyard/cli/api_spec.rb +50 -0
  57. data/spec/engineyard/cli_spec.rb +28 -0
  58. data/spec/engineyard/config_spec.rb +61 -0
  59. data/spec/engineyard/deploy_config_spec.rb +194 -0
  60. data/spec/engineyard/eyrc_spec.rb +76 -0
  61. data/spec/engineyard/repo_spec.rb +83 -0
  62. data/spec/engineyard_spec.rb +7 -0
  63. data/spec/ey/console_spec.rb +57 -0
  64. data/spec/ey/deploy_spec.rb +435 -0
  65. data/spec/ey/ey_spec.rb +23 -0
  66. data/spec/ey/init_spec.rb +123 -0
  67. data/spec/ey/list_environments_spec.rb +120 -0
  68. data/spec/ey/login_spec.rb +33 -0
  69. data/spec/ey/logout_spec.rb +24 -0
  70. data/spec/ey/logs_spec.rb +36 -0
  71. data/spec/ey/rebuild_spec.rb +18 -0
  72. data/spec/ey/recipes/apply_spec.rb +29 -0
  73. data/spec/ey/recipes/download_spec.rb +43 -0
  74. data/spec/ey/recipes/upload_spec.rb +99 -0
  75. data/spec/ey/rollback_spec.rb +73 -0
  76. data/spec/ey/scp_spec.rb +176 -0
  77. data/spec/ey/servers_spec.rb +209 -0
  78. data/spec/ey/ssh_spec.rb +273 -0
  79. data/spec/ey/status_spec.rb +45 -0
  80. data/spec/ey/timeout_deploy_spec.rb +18 -0
  81. data/spec/ey/web/disable_spec.rb +21 -0
  82. data/spec/ey/web/enable_spec.rb +26 -0
  83. data/spec/ey/web/restart_spec.rb +21 -0
  84. data/spec/ey/whoami_spec.rb +30 -0
  85. data/spec/spec_helper.rb +84 -0
  86. data/spec/support/bundled_ey +7 -0
  87. data/spec/support/fixture_recipes.tgz +0 -0
  88. data/spec/support/git_repos.rb +115 -0
  89. data/spec/support/helpers.rb +330 -0
  90. data/spec/support/matchers.rb +16 -0
  91. data/spec/support/ruby_ext.rb +13 -0
  92. data/spec/support/shared_behavior.rb +278 -0
  93. metadata +411 -0
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ey" do
4
+ context "run without arguments" do
5
+ it "prints usage information" do
6
+ expect(ey).to include("Usage:")
7
+ end
8
+ end
9
+
10
+ context "run with an argument that is not a command" do
11
+ it "tells the user that is not a command" do
12
+ ey %w[foobarbaz], :expect_failure => true
13
+ expect(@err).to include("Could not find command")
14
+ end
15
+ end
16
+
17
+ context "run a command and a bad flag" do
18
+ it "tells the user that is not a valid flag" do
19
+ ey %w[help --expect-failure], :expect_failure => true
20
+ expect(@err).to include("Unknown switches")
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,123 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ey init" do
4
+ given "integration"
5
+
6
+ let(:default_migration_command) { "rake db:migrate --trace" }
7
+
8
+ before do
9
+ login_scenario "one app, one environment"
10
+ end
11
+
12
+ before { clean_ey_yml }
13
+ after { clean_ey_yml }
14
+
15
+ context "with no ey.yml file" do
16
+ it "writes the file" do
17
+ fast_ey %w[init]
18
+
19
+ expect(ey_yml).to exist
20
+ expect_config('migrate').to eq(false)
21
+ end
22
+ end
23
+
24
+ context "with existing ey.yml file" do
25
+ let(:existing) {
26
+ {
27
+ "defaults" => {
28
+ "migrate" => false,
29
+ "migration_command" => "thor fancy:migrate",
30
+ "precompile_assets" => false,
31
+ "precompile_assets_task" => "assets:precompile",
32
+ },
33
+ "environments" => {
34
+ "my_env" => {
35
+ "default" => true,
36
+ "migrate" => true,
37
+ "migration_command" => default_migration_command,
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ before do
44
+ write_yaml(existing, 'ey.yml')
45
+ end
46
+
47
+ it "reinitializes the file" do
48
+ fast_ey %w[init]
49
+
50
+ expect_config('defaults','migration_command').to eq("thor fancy:migrate")
51
+ expect_config('defaults','migrate').to eq(false)
52
+ expect_config('defaults','precompile_assets').to eq(false)
53
+
54
+ expect_config('environments','my_env','default').to eq(true)
55
+ expect_config('environments','my_env','migrate').to eq(true)
56
+ expect_config('environments','my_env','migration_command').to eq(default_migration_command)
57
+ end
58
+
59
+ it "makes a backup when overwriting an existing file" do
60
+ fast_ey %w[init]
61
+ data = read_yaml('ey.yml.backup')
62
+ expect(data['defaults']['migration_command']).to eq('thor fancy:migrate')
63
+ end
64
+ end
65
+
66
+ context "smart defaults" do
67
+ describe "migrate" do
68
+ let(:db) { Pathname.new('db') }
69
+ let(:db_migrate) { db.join('migrate') }
70
+
71
+ context "with db/migrate directory" do
72
+ before { db_migrate.mkpath }
73
+ after { db.rmtree }
74
+
75
+ it "sets migrate to true and uses default migration command" do
76
+ fast_ey %w[init]
77
+
78
+ expect_config('migrate').to eq(true)
79
+ expect_config('migration_command').to eq(default_migration_command)
80
+ end
81
+ end
82
+
83
+ context "without db/migrate directory" do
84
+ it "sets migrate to false and doesn't write migration_command" do
85
+ expect(db_migrate).to_not exist
86
+
87
+ fast_ey %w[init]
88
+
89
+ expect_config('migrate').to eq(false)
90
+ expect_config('migration_command').to be_nil
91
+ end
92
+ end
93
+ end
94
+
95
+ context "precompile_assets" do
96
+ let(:app) { Pathname.new('app') }
97
+ let(:assets) { app.join('assets') }
98
+
99
+ context "with app/assets directory" do
100
+ before { assets.mkpath }
101
+ after { app.rmtree }
102
+
103
+ it "sets precompile_assets to true and doesn't write precompile_assets_task" do
104
+ fast_ey %w[init]
105
+
106
+ expect_config('precompile_assets').to eq(true)
107
+ expect_config('precompile_assets_task').to be_nil
108
+ end
109
+ end
110
+
111
+ context "without app/assets directory" do
112
+ it "sets precompile_assets to false and does not set an precompile_assets_task" do
113
+ expect(assets).to_not exist
114
+
115
+ fast_ey %w[init]
116
+
117
+ expect_config('precompile_assets').to eq(false)
118
+ expect_config('precompile_assets_task').to be_nil
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ey environments" do
4
+
5
+ given "integration"
6
+
7
+ before { @succeeds_on_multiple_matches = true }
8
+
9
+ def command_to_run(opts)
10
+ cmd = ["environments"]
11
+ cmd << "--environment" << opts[:environment] if opts[:environment]
12
+ cmd << "--app" << opts[:app] if opts[:app]
13
+ cmd << "--account" << opts[:account] if opts[:account]
14
+ cmd
15
+ end
16
+
17
+ def verify_ran(scenario)
18
+ expect(@out).to match(/#{scenario[:environment]}/) if scenario[:environment]
19
+ expect(@out).to match(/#{scenario[:application]}/) if scenario[:application]
20
+ end
21
+
22
+ include_examples "it takes an environment name and an app name and an account name"
23
+
24
+ context "with no apps" do
25
+ before do
26
+ login_scenario "empty"
27
+ end
28
+
29
+ it "suggests that you use environments --all" do
30
+ fast_failing_ey %w[environments]
31
+ expect(@err).to match(/Use ey environments --all to see all environments./)
32
+ end
33
+ end
34
+
35
+ context "with apps" do
36
+ before(:all) do
37
+ login_scenario "one app, many environments"
38
+ end
39
+
40
+ it "lists the environments your app is in" do
41
+ fast_ey %w[environments]
42
+ expect(@out).to include('main/rails232app')
43
+ expect(@out).to match(/giblets/)
44
+ expect(@out).to match(/bakon/)
45
+ end
46
+
47
+ it "lists the environments with specified app" do
48
+ fast_ey %w[environments --app rails232app]
49
+ expect(@out).to include('main/rails232app')
50
+ expect(@out).to match(/giblets/)
51
+ expect(@out).to match(/bakon/)
52
+ end
53
+
54
+ it "finds no environments with gibberish app" do
55
+ fast_failing_ey %w[environments --account main --app gibberish]
56
+ expect(@err).to match(/Use ey environments --all to see all environments./)
57
+ end
58
+
59
+ it "finds no environments with gibberish account" do
60
+ fast_failing_ey %w[environments --account gibberish --app rails232]
61
+ expect(@err).to match(/Use ey environments --all to see all environments./)
62
+ end
63
+
64
+ it "lists the environments that the app is in" do
65
+ fast_ey %w[environments --app rails232app]
66
+ expect(@out).to include('main/rails232app')
67
+ expect(@out).to match(/giblets/)
68
+ expect(@out).to match(/bakon/)
69
+ end
70
+
71
+ it "lists the environments that the app is in" do
72
+ fast_ey %w[environments --account main]
73
+ expect(@out).to include('main/rails232app')
74
+ expect(@out).to match(/giblets/)
75
+ expect(@out).to match(/bakon/)
76
+ end
77
+
78
+ it "lists the environments matching --environment" do
79
+ fast_ey %w[environments -e gib]
80
+ expect(@out).to include('main/rails232app')
81
+ expect(@out).to match(/giblets/)
82
+ expect(@out).not_to match(/bakon/)
83
+ end
84
+
85
+ it "reports failure to find a git repo when not in one" do
86
+ Dir.chdir(Dir.tmpdir) do
87
+ fast_failing_ey %w[environments]
88
+ expect(@err).to match(/fatal: Not a git repository \(or any of the parent directories\): .*#{Regexp.escape(Dir.tmpdir)}/)
89
+ expect(@out).not_to match(/no application configured/)
90
+ end
91
+ end
92
+
93
+ it "lists all environments that have apps with -A" do
94
+ fast_ey %w[environments -A]
95
+ expect(@out).to include("bakon")
96
+ expect(@out).to include("giblets")
97
+ end
98
+
99
+ it "outputs simply with -s" do
100
+ fast_ey %w[environments -s], :debug => false
101
+ expect(@out.split(/\n/).sort).to eq(["bakon", "giblets"])
102
+ end
103
+
104
+ it "outputs all environments (including ones with no apps) simply with -A and -s" do
105
+ fast_ey %w[environments -A -s], :debug => false
106
+ expect(@out.split(/\n/).sort).to eq(["bakon", "beef", "giblets"])
107
+ end
108
+ end
109
+ end
110
+
111
+ describe "ey environments with an ambiguous git repo" do
112
+ given "integration"
113
+ include_examples "it has an ambiguous git repo"
114
+
115
+ it "lists environments from all apps using the git repo" do
116
+ fast_ey %w[environments]
117
+ expect(@out).to include("giblets")
118
+ expect(@out).to include("keycollector_production")
119
+ end
120
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ey login" do
4
+ given "integration"
5
+
6
+ context "logged in" do
7
+ before do
8
+ login_scenario 'empty'
9
+ end
10
+
11
+ it "returns the logged in user name" do
12
+ ey %w[login]
13
+ expect(@out).to include("User Name (#{scenario_email})")
14
+ end
15
+ end
16
+
17
+ context "not logged in" do
18
+ it "prompts for authentication before outputting the logged in user" do
19
+ api_scenario "empty"
20
+
21
+ ey(%w[login], :hide_err => true) do |input|
22
+ input.puts(scenario_email)
23
+ input.puts(scenario_password)
24
+ end
25
+
26
+ expect(@out).to include("We need to fetch your API token; please log in.")
27
+ expect(@out).to include("Email:")
28
+ expect(@out).to include("Password:")
29
+
30
+ expect(@out).to include("User Name (#{scenario_email})")
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ey logout" do
4
+ given "integration"
5
+
6
+ context "logged in" do
7
+ before { login_scenario 'empty' }
8
+
9
+ it "logs you out" do
10
+ ey %w[logout]
11
+ expect(@out).to include("API token removed: #{ENV['EYRC']}")
12
+ expect(@out).to include("Run any other command to login again.")
13
+ end
14
+ end
15
+
16
+ context "not logged in" do
17
+ it "doesn't prompt for login before logging out" do
18
+ ey %w[logout]
19
+ expect(@out).not_to include("API token removed:")
20
+ expect(@out).to include("Already logged out.")
21
+ expect(@out).to include("Run any other command to login again.")
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ey logs" do
4
+ given "integration"
5
+
6
+ it "prints logs returned by awsm" do
7
+ login_scenario "one app, one environment"
8
+ fast_ey %w[logs -e giblets]
9
+ expect(@out).to match(/MAIN LOG OUTPUT/)
10
+ expect(@out).to match(/CUSTOM LOG OUTPUT/)
11
+ expect(@err).to eq('')
12
+ end
13
+
14
+ it "complains when it can't infer the environment" do
15
+ login_scenario "one app, many environments"
16
+ fast_failing_ey %w[logs]
17
+ expect(@err).to match(/Multiple environments possible, please be more specific/i)
18
+ end
19
+ end
20
+
21
+ describe "ey logs" do
22
+ given "integration"
23
+
24
+ def command_to_run(opts)
25
+ cmd = ["logs"]
26
+ cmd << "--environment" << opts[:environment] if opts[:environment]
27
+ cmd << "--account" << opts[:account] if opts[:account]
28
+ cmd
29
+ end
30
+
31
+ def verify_ran(scenario)
32
+ expect(@out).to match(/Main logs for #{scenario[:environment]}/)
33
+ end
34
+
35
+ include_examples "it takes an environment name and an account name"
36
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ey rebuild" do
4
+ given "integration"
5
+
6
+ def command_to_run(opts)
7
+ cmd = ["rebuild"]
8
+ cmd << "--environment" << opts[:environment] if opts[:environment]
9
+ cmd << "--account" << opts[:account] if opts[:account]
10
+ cmd
11
+ end
12
+
13
+ def verify_ran(scenario)
14
+ expect(@out).to match(/Updating instances on #{scenario[:account]} \/ #{scenario[:environment]}/)
15
+ end
16
+
17
+ include_examples "it takes an environment name and an account name"
18
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ey recipes apply" do
4
+ given "integration"
5
+
6
+ def command_to_run(opts)
7
+ cmd = %w[recipes apply]
8
+ cmd << "-e" << opts[:environment] if opts[:environment]
9
+ cmd << "--account" << opts[:account] if opts[:account]
10
+ cmd
11
+ end
12
+
13
+ def verify_ran(scenario)
14
+ expect(@out).to match(/Uploaded recipes started for #{scenario[:environment]}/)
15
+ end
16
+
17
+ include_examples "it takes an environment name and an account name"
18
+
19
+ it "fails when given a bad option" do
20
+ fast_failing_ey %w[web enable --lots --of --bogus --options]
21
+ expect(@err).to include("Unknown switches")
22
+ end
23
+ end
24
+
25
+ describe "ey recipes apply with an ambiguous git repo" do
26
+ given "integration"
27
+ def command_to_run(_) %w[recipes apply] end
28
+ include_examples "it requires an unambiguous git repo"
29
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ey recipes download" do
4
+ given "integration"
5
+ use_git_repo('default')
6
+
7
+ before(:each) do
8
+ FileUtils.rm_rf('cookbooks')
9
+ end
10
+
11
+ after(:each) do
12
+ # This test creates + destroys the cookbooks/ directory, thus
13
+ # rendering the git repo unsuitable for reuse.
14
+ EY.refresh_git_repo('default')
15
+ end
16
+
17
+ def command_to_run(opts)
18
+ cmd = %w[recipes download]
19
+ cmd << "--environment" << opts[:environment] if opts[:environment]
20
+ cmd << "--account" << opts[:account] if opts[:account]
21
+ cmd
22
+ end
23
+
24
+ def verify_ran(scenario)
25
+ expect(@out).to match(/Recipes downloaded successfully for #{scenario[:environment]}/)
26
+ expect(File.read('cookbooks/README')).to eq("Remove this file to clone an upstream git repository of cookbooks\n")
27
+ end
28
+
29
+ include_examples "it takes an environment name and an account name"
30
+
31
+ it "fails when cookbooks/ already exists" do
32
+ login_scenario "one app, one environment"
33
+ Dir.mkdir("cookbooks")
34
+ ey %w[recipes download], :expect_failure => true
35
+ expect(@err).to match(/cookbooks.*already exists/i)
36
+ end
37
+ end
38
+
39
+ describe "ey recipes download with an ambiguous git repo" do
40
+ given "integration"
41
+ def command_to_run(_) %w[recipes download] end
42
+ include_examples "it requires an unambiguous git repo"
43
+ end