heroploy 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/lib/generators/heroploy/install/install_generator.rb +7 -5
  4. data/lib/heroploy/commands/checks.rb +22 -20
  5. data/lib/heroploy/commands/git.rb +43 -41
  6. data/lib/heroploy/commands/heroku.rb +13 -11
  7. data/lib/heroploy/commands/shell.rb +11 -9
  8. data/lib/heroploy/config/deployment_config.rb +24 -0
  9. data/lib/heroploy/config/environment.rb +21 -0
  10. data/lib/heroploy/config/environment_checks.rb +16 -0
  11. data/lib/heroploy/tasks/check_task_lib.rb +57 -57
  12. data/lib/heroploy/tasks/deploy_task_lib.rb +22 -23
  13. data/lib/heroploy/tasks/env_task_lib.rb +43 -42
  14. data/lib/heroploy/tasks/tasks.rake +3 -2
  15. data/lib/heroploy/version.rb +1 -1
  16. data/lib/heroploy.rb +0 -6
  17. data/spec/factories.rb +8 -8
  18. data/spec/lib/generators/heroploy/install_generator_spec.rb +1 -1
  19. data/spec/lib/heroploy/commands/checks_spec.rb +2 -2
  20. data/spec/lib/heroploy/commands/git_spec.rb +9 -2
  21. data/spec/lib/heroploy/commands/heroku_spec.rb +2 -2
  22. data/spec/lib/heroploy/commands/shell_spec.rb +12 -5
  23. data/spec/lib/heroploy/config/deployment_config_spec.rb +42 -0
  24. data/spec/lib/heroploy/config/environment_checks_spec.rb +30 -0
  25. data/spec/lib/heroploy/config/environment_spec.rb +30 -0
  26. data/spec/lib/heroploy/tasks/check_all_spec.rb +1 -1
  27. data/spec/lib/heroploy/tasks/check_branch_spec.rb +3 -3
  28. data/spec/lib/heroploy/tasks/check_pushed_spec.rb +3 -3
  29. data/spec/lib/heroploy/tasks/check_remote_spec.rb +2 -2
  30. data/spec/lib/heroploy/tasks/check_staged_spec.rb +4 -4
  31. data/spec/spec_helper.rb +9 -0
  32. data/spec/support/customer_matchers/environment_matcher.rb +36 -0
  33. data/spec/support/shared_contexts/rake.rb +5 -5
  34. data/spec/support/shell_support.rb +6 -6
  35. metadata +14 -5
  36. data/lib/heroploy/config/checks_config.rb +0 -16
  37. data/lib/heroploy/config/deploy_config.rb +0 -24
  38. data/lib/heroploy/config/env_config.rb +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 356baf2c9b896ba5dddc86702c4b549e7af81824
4
- data.tar.gz: 79fb1cea8d3206b14e22c37f087bf967702bcd99
3
+ metadata.gz: de74cf40268ad2d31c7e06ef60d7f8312ee936a6
4
+ data.tar.gz: e2257f2a4f5d83970c43942db5e4b16d95c963d7
5
5
  SHA512:
6
- metadata.gz: c0963dd5196fffa11e2307f5481dbd02bd0d75b794bba7427a487fa2657a5154c524fa1d7639c080862d29da35bc199dca2c7007fdcde3df1cf26444c7458960
7
- data.tar.gz: 14460f37d4ebe158c98d8a3c4dce756f83064a1b9d96cd8dc10658a1a0cf5d763ffe4fc846fdbc5771542066dfe9e88aa5ba8a6d76aa23c175b3271fe0a69c3e
6
+ metadata.gz: 87a969dad8ff6d44f9370fcb78fb15151ba6abcd2a6401938244c2fb323ec0f05fec7ab6717b5e2825d6b427ea48b23242918f38936955e8032f09e9cf4ef0e5
7
+ data.tar.gz: 1c9678265b500863c37074c97ed9b4fe897915554d236ed8f509387ad1c3e27e2ad67e624a1e5041287533a7dccecedb044f351e43397e0b18676e6b1eae0ea5
data/README.md CHANGED
@@ -52,6 +52,7 @@ environments:
52
52
  ```
53
53
 
54
54
  This file:
55
+
55
56
  * Describes ```development```, ```staging``` and ```production``` deployment rules for three Heroku apps (named ```my-development-app```, ```my-staging-app``` and ```my-production-app``` on Heroku).
56
57
  * Allows any branch to be pushed directly to ```development```.
57
58
  * Only allows ```master``` to be pushed to ```staging```, and requires all changes to have first been pushed to ```origin```.
@@ -1,9 +1,11 @@
1
1
  module Heroploy
2
- class InstallGenerator < Rails::Generators::Base
3
- source_root File.expand_path('../templates', __FILE__)
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
4
5
 
5
- def copy_config
6
- copy_file "config/heroploy.yml"
7
- end
6
+ def copy_config
7
+ copy_file "config/heroploy.yml"
8
+ end
9
+ end
8
10
  end
9
11
  end
@@ -1,30 +1,32 @@
1
- module Commands
2
- module Checks
3
- def check_remote(remote)
4
- unless git_remote_exists?(remote)
5
- raise "Could not find remote '#{remote}'"
1
+ module Heroploy
2
+ module Commands
3
+ module Checks
4
+ def check_remote(remote)
5
+ unless git_remote_exists?(remote)
6
+ raise "Could not find remote '#{remote}'"
7
+ end
6
8
  end
7
- end
8
9
 
9
- def check_pushed(branch_name)
10
- unless git_remote_has_branch?('origin', branch_name)
11
- raise "Branch #{branch_name} doesn't exist in origin"
12
- end
10
+ def check_pushed(branch_name)
11
+ unless git_remote_has_branch?('origin', branch_name)
12
+ raise "Branch #{branch_name} doesn't exist in origin"
13
+ end
13
14
 
14
- if git_remote_behind?('origin', branch_name) then
15
- raise "Branch #{branch_name} is behind origin/#{branch_name}"
15
+ if git_remote_behind?('origin', branch_name) then
16
+ raise "Branch #{branch_name} is behind origin/#{branch_name}"
17
+ end
16
18
  end
17
- end
18
19
 
19
- def check_branch(branch_name, valid_branch, env_name)
20
- unless branch_name == valid_branch
21
- raise "Cannot deploy branch #{branch_name} to #{env_name}"
20
+ def check_branch(branch_name, valid_branch, env_name)
21
+ unless branch_name == valid_branch
22
+ raise "Cannot deploy branch #{branch_name} to #{env_name}"
23
+ end
22
24
  end
23
- end
24
25
 
25
- def check_staged(remote, branch_name, env_name)
26
- unless git_staged?(remote, branch_name)
27
- raise "Changes not yet staged on #{env_name}"
26
+ def check_staged(remote, branch_name, env_name)
27
+ unless git_staged?(remote, branch_name)
28
+ raise "Changes not yet staged on #{env_name}"
29
+ end
28
30
  end
29
31
  end
30
32
  end
@@ -1,46 +1,48 @@
1
1
  require 'heroploy/commands/shell'
2
2
 
3
- module Commands
4
- module Git
5
- def git_fetch
6
- Shell.exec "git fetch"
7
- end
8
-
9
- def current_branch
10
- branch = Shell.eval "git rev-parse --abbrev-ref HEAD"
11
- branch.strip
12
- end
13
-
14
- def git_push_to_master(remote, local_branch)
15
- if ENV['force'] == 'true' then opts = "--force " end
16
- Shell.exec "git push #{opts}#{remote} #{local_branch}:master"
17
- end
18
-
19
- def git_remote_exists?(name)
20
- remotes = Shell.eval("git remote").strip.split(/\s+/)
21
- remotes.include?(name)
22
- end
23
-
24
- def git_remote_has_branch?(remote, branch_name)
25
- branches = Shell.eval("git branch -r").strip.split(/\s+/)
26
- branches.include?("#{remote}/#{branch_name}")
27
- end
28
-
29
- def git_remote_behind?(remote, remote_branch_name, local_branch_name = nil)
30
- if local_branch_name.nil? then local_branch_name = remote_branch_name end
31
- !Shell.eval("git log #{remote}/#{remote_branch_name}..#{local_branch_name}").empty?
32
- end
33
-
34
- def git_staged?(remote, local_branch)
35
- !git_remote_behind?(remote, 'master', local_branch)
36
- end
37
-
38
- def git_tag(tag, message)
39
- Shell.exec("git tag -a #{tag} -m \"#{message}\"")
40
- end
41
-
42
- def git_push_tag(tag)
43
- Shell.exec("git push origin #{tag}")
3
+ module Heroploy
4
+ module Commands
5
+ module Git
6
+ def git_fetch
7
+ Shell.exec "git fetch"
8
+ end
9
+
10
+ def current_branch
11
+ branch = Shell.eval "git rev-parse --abbrev-ref HEAD"
12
+ branch.strip
13
+ end
14
+
15
+ def git_push_to_master(remote, local_branch)
16
+ if ENV['force'] == 'true' then opts = "--force " end
17
+ Shell.exec "git push #{opts}#{remote} #{local_branch}:master"
18
+ end
19
+
20
+ def git_remote_exists?(name)
21
+ remotes = Shell.eval("git remote").strip.split(/\s+/)
22
+ remotes.include?(name)
23
+ end
24
+
25
+ def git_remote_has_branch?(remote, branch_name)
26
+ branches = Shell.eval("git branch -r").strip.split(/\s+/)
27
+ branches.include?("#{remote}/#{branch_name}")
28
+ end
29
+
30
+ def git_remote_behind?(remote, remote_branch_name, local_branch_name = nil)
31
+ if local_branch_name.nil? then local_branch_name = remote_branch_name end
32
+ !Shell.eval("git log #{remote}/#{remote_branch_name}..#{local_branch_name}").empty?
33
+ end
34
+
35
+ def git_staged?(remote, local_branch)
36
+ !git_remote_behind?(remote, 'master', local_branch)
37
+ end
38
+
39
+ def git_tag(tag, message)
40
+ Shell.exec("git tag -a #{tag} -m \"#{message}\"")
41
+ end
42
+
43
+ def git_push_tag(tag)
44
+ Shell.exec("git push origin #{tag}")
45
+ end
44
46
  end
45
47
  end
46
48
  end
@@ -1,18 +1,20 @@
1
1
  require 'heroploy/commands/shell'
2
2
 
3
- module Commands
4
- module Heroku
5
- def heroku_exec(cmd, app_name)
6
- Shell.exec "heroku #{cmd} --app #{app_name}"
7
- end
3
+ module Heroploy
4
+ module Commands
5
+ module Heroku
6
+ def heroku_exec(cmd, app_name)
7
+ Shell.exec "heroku #{cmd} --app #{app_name}"
8
+ end
8
9
 
9
- def heroku_run(cmd, app_name)
10
- heroku_exec("run #{cmd}", app_name)
11
- end
10
+ def heroku_run(cmd, app_name)
11
+ heroku_exec("run #{cmd}", app_name)
12
+ end
12
13
 
13
- def heroku_migrate(app_name)
14
- Bundler.with_clean_env do
15
- heroku_run("rake db:migrate", app_name)
14
+ def heroku_migrate(app_name)
15
+ Bundler.with_clean_env do
16
+ heroku_run("rake db:migrate", app_name)
17
+ end
16
18
  end
17
19
  end
18
20
  end
@@ -1,11 +1,13 @@
1
- class Shell
2
- extend FileUtils
3
-
4
- def self.eval(cmd)
5
- `#{cmd}`
6
- end
7
-
8
- def self.exec(cmd)
9
- sh cmd
1
+ module Heroploy
2
+ class Shell
3
+ extend FileUtils
4
+
5
+ def self.eval(cmd)
6
+ `#{cmd}`
7
+ end
8
+
9
+ def self.exec(cmd)
10
+ sh cmd
11
+ end
10
12
  end
11
13
  end
@@ -0,0 +1,24 @@
1
+ require 'heroploy/config/deployment_config'
2
+ require 'heroploy/config/environment'
3
+
4
+ module Heroploy
5
+ module Config
6
+ class DeploymentConfig
7
+ attr_accessor :environments
8
+
9
+ def [](env_name)
10
+ environments.select{ |env| env.name == env_name }.first
11
+ end
12
+
13
+ def initialize(attrs = {})
14
+ unless attrs['environments'].nil?
15
+ @environments = attrs['environments'].map { |name, attrs| Environment.new(name, attrs) }
16
+ end
17
+ end
18
+
19
+ def self.load
20
+ DeploymentConfig.new(YAML::load(File.open('config/heroploy.yml')))
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,21 @@
1
+ require 'heroploy/config/environment_checks'
2
+
3
+ module Heroploy
4
+ module Config
5
+ class Environment
6
+ attr_accessor :name
7
+ attr_accessor :remote
8
+ attr_accessor :app
9
+ attr_accessor :tag
10
+ attr_accessor :checks
11
+
12
+ def initialize(name = nil, attrs = {})
13
+ @name = name
14
+ @remote = attrs['remote'] || name
15
+ @app = attrs['app']
16
+ @tag = attrs['tag']
17
+ @checks = EnvironmentChecks.new(attrs['checks'])
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,16 @@
1
+ module Heroploy
2
+ module Config
3
+ class EnvironmentChecks
4
+ attr_accessor :pushed
5
+ attr_accessor :branch
6
+ attr_accessor :staged
7
+
8
+ def initialize(attrs = {})
9
+ attrs ||= {}
10
+ @pushed = attrs['pushed']
11
+ @branch = attrs['branch']
12
+ @staged = attrs['staged'] == true ? 'staging' : attrs['staged']
13
+ end
14
+ end
15
+ end
16
+ end
@@ -4,80 +4,80 @@ require 'heroploy/commands/heroku'
4
4
  require 'heroploy/commands/git'
5
5
  require 'heroploy/commands/checks'
6
6
 
7
- require 'heroploy/config/deploy_config'
8
-
9
7
  module Heroploy
10
- class CheckTaskLib < ::Rake::TaskLib
11
- include ::Rake::DSL if defined?(::Rake::DSL)
12
-
13
- include Commands::Git
14
- include Commands::Heroku
15
- include Commands::Checks
8
+ module Tasks
9
+ class CheckTaskLib < ::Rake::TaskLib
10
+ include ::Rake::DSL if defined?(::Rake::DSL)
16
11
 
17
- attr_accessor :deploy_config
18
- attr_accessor :env_config
19
- attr_accessor :defined_tasks
12
+ include Commands::Git
13
+ include Commands::Heroku
14
+ include Commands::Checks
20
15
 
21
- def initialize(deploy_config, env_config)
22
- @deploy_config = deploy_config
23
- @env_config = env_config
24
- @defined_tasks = []
25
- define
26
- end
16
+ attr_accessor :deploy_config
17
+ attr_accessor :env_config
18
+ attr_accessor :defined_tasks
27
19
 
28
- def define
29
- define_remote_check
30
- define_pushed_check
31
- define_branch_check
32
- define_staged_check
33
- define_all_check
34
- end
20
+ def initialize(deploy_config, env_config)
21
+ @deploy_config = deploy_config
22
+ @env_config = env_config
23
+ @defined_tasks = []
24
+ define
25
+ end
35
26
 
36
- def define_remote_check
37
- desc "check remote exists for #{env_config.name}"
38
- task :remote do
39
- remote = env_config.remote
40
- check_remote(remote)
27
+ def define
28
+ define_remote_check
29
+ define_pushed_check
30
+ define_branch_check
31
+ define_staged_check
32
+ define_all_check
41
33
  end
34
+
35
+ def define_remote_check
36
+ desc "check remote exists for #{env_config.name}"
37
+ task :remote do
38
+ remote = env_config.remote
39
+ check_remote(remote)
40
+ end
42
41
 
43
- @defined_tasks << :remote
44
- end
42
+ @defined_tasks << :remote
43
+ end
45
44
 
46
- def define_pushed_check
47
- if env_config.checks.pushed then
48
- desc "check changes have been pushed to origin"
49
- task :pushed do
50
- check_pushed(current_branch)
45
+ def define_pushed_check
46
+ if env_config.checks.pushed then
47
+ desc "check changes have been pushed to origin"
48
+ task :pushed do
49
+ check_pushed(current_branch)
50
+ end
51
+ @defined_tasks << :pushed
51
52
  end
52
- @defined_tasks << :pushed
53
53
  end
54
- end
55
54
 
56
- def define_branch_check
57
- if env_config.checks.branch then
58
- desc "check we can deploy to #{env_config.name} from the current branch"
59
- task :branch do
60
- valid_branch = env_config.checks.branch
61
- check_branch(current_branch, valid_branch, env_config.name)
55
+ def define_branch_check
56
+ if env_config.checks.branch then
57
+ desc "check we can deploy to #{env_config.name} from the current branch"
58
+ task :branch do
59
+ valid_branch = env_config.checks.branch
60
+ check_branch(current_branch, valid_branch, env_config.name)
61
+ end
62
+ @defined_tasks << :branch
62
63
  end
63
- @defined_tasks << :branch
64
64
  end
65
- end
66
65
 
67
- def define_staged_check
68
- if env_config.checks.staged then
69
- desc "check the changes have already been staged"
70
- task :staged do
71
- staging_env_config = deploy_config[env_config.checks.staged]
72
- check_staged(staging_env_config.remote, current_branch, staging_env_config.name)
66
+ def define_staged_check
67
+ if env_config.checks.staged then
68
+ desc "check the changes have already been staged"
69
+ task :staged do
70
+ staging_env_config = deploy_config[env_config.checks.staged]
71
+ check_staged(staging_env_config.remote, current_branch, staging_env_config.name)
72
+ end
73
+ @defined_tasks << :staged
73
74
  end
74
- @defined_tasks << :staged
75
75
  end
76
- end
77
76
 
78
- def define_all_check
79
- desc "do all the checks for #{env_config.name}"
80
- task :all => @defined_tasks
77
+ def define_all_check
78
+ desc "do all the checks for #{env_config.name}"
79
+ task :all => @defined_tasks
80
+ end
81
81
  end
82
82
  end
83
83
  end
@@ -1,38 +1,37 @@
1
1
  require 'rake/tasklib'
2
2
 
3
- require 'heroploy/commands/heroku'
4
3
  require 'heroploy/commands/git'
5
- require 'heroploy/commands/checks'
6
-
7
- require 'heroploy/config/deploy_config'
8
4
  require 'heroploy/tasks/env_task_lib'
9
5
 
10
6
  module Heroploy
11
- class DeployTaskLib < ::Rake::TaskLib
12
- include ::Rake::DSL if defined?(::Rake::DSL)
7
+ module Tasks
8
+ class DeployTaskLib < ::Rake::TaskLib
9
+ include ::Rake::DSL if defined?(::Rake::DSL)
10
+ include Commands::Git
13
11
 
14
- attr_accessor :deploy_config
12
+ attr_accessor :deployment_config
15
13
 
16
- def initialize(deploy_config)
17
- @deploy_config = deploy_config
18
- define
19
- end
14
+ def initialize(deployment_config)
15
+ @deployment_config = deployment_config
16
+ define
17
+ end
20
18
 
21
- def define
22
- define_fetch_task
23
- define_env_tasks
24
- end
19
+ def define
20
+ define_fetch_task
21
+ define_env_tasks
22
+ end
25
23
 
26
- def define_fetch_task
27
- desc 'do a git fetch'
28
- task :fetch do
29
- git_fetch
24
+ def define_fetch_task
25
+ desc 'do a git fetch'
26
+ task :fetch do
27
+ git_fetch
28
+ end
30
29
  end
31
- end
32
30
 
33
- def define_env_tasks
34
- deploy_config.environments.each do |env_config|
35
- EnvTaskLib.new(deploy_config, env_config)
31
+ def define_env_tasks
32
+ deployment_config.environments.each do |env|
33
+ EnvTaskLib.new(deployment_config, env)
34
+ end
36
35
  end
37
36
  end
38
37
  end
@@ -4,64 +4,65 @@ require 'heroploy/commands/heroku'
4
4
  require 'heroploy/commands/git'
5
5
  require 'heroploy/commands/checks'
6
6
 
7
- require 'heroploy/config/deploy_config'
8
7
  require 'heroploy/tasks/check_task_lib'
9
8
 
10
9
  module Heroploy
11
- class EnvTaskLib < ::Rake::TaskLib
12
- include ::Rake::DSL if defined?(::Rake::DSL)
10
+ module Tasks
11
+ class EnvTaskLib < ::Rake::TaskLib
12
+ include ::Rake::DSL if defined?(::Rake::DSL)
13
13
 
14
- include Commands::Git
15
- include Commands::Heroku
16
- include Commands::Checks
14
+ include Commands::Git
15
+ include Commands::Heroku
16
+ include Commands::Checks
17
17
 
18
- attr_accessor :deploy_config
19
- attr_accessor :env_config
18
+ attr_accessor :deployment_config
19
+ attr_accessor :env
20
20
 
21
- def initialize(deploy_config, env_config)
22
- @deploy_config = deploy_config
23
- @env_config = env_config
24
- define
25
- end
21
+ def initialize(deployment_config, env)
22
+ @deployment_config = deployment_config
23
+ @env = env
24
+ define
25
+ end
26
26
 
27
- def define
28
- namespace env_config.name do
29
- define_check_tasks
30
- define_git_tasks
31
- define_heroku_tasks
27
+ def define
28
+ namespace env.name do
29
+ define_check_tasks
30
+ define_git_tasks
31
+ define_heroku_tasks
32
+ end
32
33
  end
33
- end
34
34
 
35
- def define_check_tasks
36
- namespace :check do
37
- CheckTaskLib.new(deploy_config, env_config)
35
+ def define_check_tasks
36
+ namespace :check do
37
+ CheckTaskLib.new(deployment_config, env)
38
+ end
38
39
  end
39
- end
40
40
 
41
- def define_git_tasks
42
- desc "push the current branch to master on #{env_config.name}"
43
- task :push do
44
- git_push_to_master(env_config.remote, current_branch)
45
- end
41
+ def define_git_tasks
42
+ desc "push the current branch to master on #{env.name}"
43
+ task :push do
44
+ git_push_to_master(env.remote, current_branch)
45
+ end
46
46
 
47
- desc "tag the deployment to #{env_config.name}"
48
- task :tag do
49
- if env_config.tag then
50
- tag = DateTime.now.strftime(env_config.tag)
51
- git_tag(tag, "Deployed #{current_branch} to #{env_config.name}")
52
- git_push_tag(tag)
47
+ desc "tag the deployment to #{env.name}"
48
+ task :tag do
49
+ if env.tag then
50
+ tag = DateTime.now.strftime(env.tag)
51
+ git_tag(tag, "Deployed #{current_branch} to #{env.name}")
52
+ git_push_tag(tag)
53
+ end
53
54
  end
54
55
  end
55
- end
56
56
 
57
- def define_heroku_tasks
58
- desc "run database migrations on #{env_config.name}"
59
- task :migrate do
60
- heroku_migrate(env_config.app)
61
- end
57
+ def define_heroku_tasks
58
+ desc "run database migrations on #{env.name}"
59
+ task :migrate do
60
+ heroku_migrate(env.app)
61
+ end
62
62
 
63
- desc "deploy to #{env_config.name}"
64
- task :deploy => ['check:all', :push, :migrate, :tag]
63
+ desc "deploy to #{env.name}"
64
+ task :deploy => ['check:all', :push, :migrate, :tag]
65
+ end
65
66
  end
66
67
  end
67
68
  end
@@ -1,9 +1,10 @@
1
+ require 'heroploy/config/deployment_config'
1
2
  require 'heroploy/tasks/deploy_task_lib'
2
3
 
3
4
  namespace :heroploy do
4
5
  begin
5
- deploy_config = DeployConfig.load
6
- Heroploy::DeployTaskLib.new(deploy_config)
6
+ deployment_config = Heroploy::Config::DeploymentConfig.load
7
+ Heroploy::Tasks::DeployTaskLib.new(deployment_config)
7
8
  rescue Errno::ENOENT
8
9
  puts "Warning: no config file present for Heroploy. Run 'rails generate heroploy:install' or add a heroploy.yml file to your project."
9
10
  end
@@ -1,3 +1,3 @@
1
1
  module Heroploy
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
data/lib/heroploy.rb CHANGED
@@ -2,9 +2,3 @@ require "rails"
2
2
 
3
3
  require "heroploy/version"
4
4
  require "heroploy/engine" if defined?(Rails) && Rails::VERSION::MAJOR >= 3
5
-
6
- module Heroploy
7
- def self.root
8
- Pathname.new(File.expand_path '../..', __FILE__)
9
- end
10
- end
data/spec/factories.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  FactoryGirl.define do
2
- factory :checks_config do
2
+ factory :environment_checks, :class => Heroploy::Config::EnvironmentChecks do
3
3
  pushed false
4
4
  staged false
5
5
  branch nil
@@ -23,24 +23,24 @@ FactoryGirl.define do
23
23
  end
24
24
  end
25
25
 
26
- factory :env_config do
27
- checks { build(:checks_config) }
26
+ factory :environment, :class => Heroploy::Config::Environment do
27
+ checks { build(:environment_checks) }
28
28
 
29
29
  [:development, :staging, :production].each do |t|
30
30
  trait t do
31
31
  name t.to_s
32
32
  remote t.to_s
33
- checks { build(:checks_config, t) }
33
+ checks { build(:environment_checks, t) }
34
34
  end
35
35
  end
36
36
  end
37
37
 
38
- factory :deploy_config do
38
+ factory :deployment_config, :class => Heroploy::Config::DeploymentConfig do
39
39
  environments {
40
40
  [
41
- build(:env_config, :development),
42
- build(:env_config, :staging),
43
- build(:env_config, :production)
41
+ build(:environment, :development),
42
+ build(:environment, :staging),
43
+ build(:environment, :production)
44
44
  ]
45
45
  }
46
46
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require File.expand_path('../../../../../lib/generators/heroploy/install/install_generator', __FILE__)
3
3
 
4
- describe Heroploy::InstallGenerator do
4
+ describe Heroploy::Generators::InstallGenerator do
5
5
  include_context "generator"
6
6
 
7
7
  it "copies the heroploy.yml template" do
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Commands::Checks do
3
+ describe Heroploy::Commands::Checks do
4
4
  before(:each) do
5
5
  stub_shell
6
6
  end
7
7
 
8
- let(:commands) { Object.new.extend(Commands::Checks) }
8
+ let(:commands) { Object.new.extend(Heroploy::Commands::Checks) }
9
9
 
10
10
  describe "#check_remote" do
11
11
  it "invokes git_remote_exists? to check the remote" do
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Commands::Git do
3
+ describe Heroploy::Commands::Git do
4
4
  before(:each) do
5
5
  stub_shell
6
6
  end
7
7
 
8
- let(:commands) { Object.new.extend(Commands::Git) }
8
+ let(:commands) { Object.new.extend(Heroploy::Commands::Git) }
9
9
 
10
10
  context "#git_fetch" do
11
11
  it "executes a git fetch" do
@@ -115,4 +115,11 @@ describe Commands::Git do
115
115
  commands.git_tag("my-tag", "my message")
116
116
  end
117
117
  end
118
+
119
+ context "#git_push_tag" do
120
+ it "pushes the tag to origin" do
121
+ expect_command("git push origin my-tag")
122
+ commands.git_push_tag("my-tag")
123
+ end
124
+ end
118
125
  end
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Commands::Heroku do
3
+ describe Heroploy::Commands::Heroku do
4
4
  before(:each) do
5
5
  stub_shell
6
6
  end
7
7
 
8
- let(:commands) { Object.new.extend(Commands::Heroku) }
8
+ let(:commands) { Object.new.extend(Heroploy::Commands::Heroku) }
9
9
 
10
10
  context "#heroku_exec" do
11
11
  it "executes the heroku command for the given app" do
@@ -1,16 +1,23 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Shell do
3
+ describe Heroploy::Shell do
4
4
  context "#eval" do
5
5
  it "evaluates the given command using backticks" do
6
- expect(Shell).to receive(:`).with('date')
7
- Shell.eval('date')
6
+ expect(Heroploy::Shell).to receive(:`).with('date')
7
+ Heroploy::Shell.eval('date')
8
8
  end
9
9
 
10
10
  it "returns the standard output from the shell command" do
11
11
  expected_output = "Sun 19 Jan 2014 01:20:23 GMT\n"
12
- expect(Shell).to receive(:`).and_return(expected_output)
13
- expect(Shell.eval('date')).to eq(expected_output)
12
+ expect(Heroploy::Shell).to receive(:`).and_return(expected_output)
13
+ expect(Heroploy::Shell.eval('date')).to eq(expected_output)
14
+ end
15
+ end
16
+
17
+ context "#exec" do
18
+ it "executes the given command on the shell" do
19
+ expect(Heroploy::Shell).to receive(:sh).with('puts "foo"')
20
+ Heroploy::Shell.exec('puts "foo"')
14
21
  end
15
22
  end
16
23
  end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe Heroploy::Config::DeploymentConfig do
4
+ before(:each) { stub_shell }
5
+
6
+ let(:attrs) { {'environments' => {'staging' => {}, 'production' => {}}} }
7
+
8
+ subject(:deployment_config) { Heroploy::Config::DeploymentConfig.new(attrs) }
9
+
10
+ context "#initialize" do
11
+ context "it initializes its environments" do
12
+ its(:environments) { should include an_environment_named(:staging) }
13
+ its(:environments) { should include an_environment_named(:production) }
14
+ end
15
+ end
16
+
17
+ context "#[]" do
18
+ it "returns the environment with the given name, if one exists" do
19
+ expect(deployment_config['staging']).to be_an_environment_named(:staging)
20
+ end
21
+
22
+ it "returns nil otherwise" do
23
+ expect(deployment_config['development']).to be_nil
24
+ end
25
+ end
26
+
27
+ context ".load" do
28
+ let(:yaml_config) do
29
+ <<-END
30
+ environments:
31
+ heroku:
32
+ app: my-app
33
+ END
34
+ end
35
+
36
+ it "returns a new instance of DeploymentConfig initialized by the heroploy config file" do
37
+ File.stub(:open).with('config/heroploy.yml').and_return(yaml_config)
38
+ deployment_config = Heroploy::Config::DeploymentConfig.load
39
+ expect(deployment_config.environments).to include an_environment_named(:heroku)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Heroploy::Config::EnvironmentChecks do
4
+ attr_accessor :pushed
5
+ attr_accessor :branch
6
+ attr_accessor :staged
7
+
8
+ describe "#initialize" do
9
+ context "it initializes the accessors" do
10
+ let(:pushed) { true }
11
+ let(:branch_name) { 'my-branch' }
12
+ let(:staging_env_name) { 'my-staging-environment' }
13
+ let(:attrs) { {'pushed' => pushed, 'branch' => branch_name, 'staged' => staging_env_name} }
14
+
15
+ subject(:environment_checks) { Heroploy::Config::EnvironmentChecks.new(attrs) }
16
+
17
+ its(:pushed) { should eq(pushed) }
18
+ its(:branch) { should eq(branch_name) }
19
+ its(:staged) { should eq(staging_env_name) }
20
+ end
21
+
22
+ context "if no staging environment name is given" do
23
+ subject(:environment_checks) { Heroploy::Config::EnvironmentChecks.new({'staged' => true}) }
24
+
25
+ it "assumed the staging environment is called 'staging'" do
26
+ expect(environment_checks.staged).to eq('staging')
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Heroploy::Config::Environment do
4
+ let(:env_name) { 'production' }
5
+
6
+ describe "#initialize" do
7
+ context "it initializes the accessors" do
8
+ let(:remote_name) { 'my-remote' }
9
+ let(:app_name) { 'my-app' }
10
+ let(:tag) { 'my-tag' }
11
+ let(:attrs) { {'remote' => remote_name, 'app' => app_name, 'tag' => tag} }
12
+
13
+ subject(:environment) { Heroploy::Config::Environment.new(env_name, attrs) }
14
+
15
+ its(:name) { should eq(env_name) }
16
+ its(:remote) { should eq(remote_name) }
17
+ its(:app) { should eq(app_name) }
18
+ its(:tag) { should eq(tag) }
19
+ its(:checks) { should be_instance_of(Heroploy::Config::EnvironmentChecks) }
20
+ end
21
+
22
+ context "if no remote name is given" do
23
+ subject(:environment) { Heroploy::Config::Environment.new(env_name, {}) }
24
+
25
+ it "uses the environment name for the remote" do
26
+ expect(environment.remote).to eq(env_name)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,5 @@
1
1
  describe "check:all" do
2
- let(:environment) { build(:env_config, :production) }
2
+ let(:environment) { build(:environment, :production) }
3
3
 
4
4
  context "in all cases" do
5
5
  include_context "rake"
@@ -1,10 +1,10 @@
1
1
  describe "check:branch" do
2
- let(:environment) { build(:env_config, :production) }
2
+ let(:environment) { build(:environment, :production) }
3
3
  include_context "rake"
4
4
 
5
5
  it "invokes :check_branch" do
6
- Heroploy::CheckTaskLib.any_instance.stub(:current_branch).and_return("my-branch")
7
- expect_any_instance_of(Heroploy::CheckTaskLib).to receive(:check_branch).with("my-branch", "master", "production")
6
+ Heroploy::Tasks::CheckTaskLib.any_instance.stub(:current_branch).and_return("my-branch")
7
+ expect_any_instance_of(Heroploy::Tasks::CheckTaskLib).to receive(:check_branch).with("my-branch", "master", "production")
8
8
  task.invoke
9
9
  end
10
10
  end
@@ -1,10 +1,10 @@
1
1
  describe "check:pushed" do
2
- let(:environment) { build(:env_config, :production) }
2
+ let(:environment) { build(:environment, :production) }
3
3
  include_context "rake"
4
4
 
5
5
  it "invokes :check_pushed" do
6
- Heroploy::CheckTaskLib.any_instance.stub(:current_branch).and_return("my-branch")
7
- expect_any_instance_of(Heroploy::CheckTaskLib).to receive(:check_pushed).with("my-branch")
6
+ Heroploy::Tasks::CheckTaskLib.any_instance.stub(:current_branch).and_return("my-branch")
7
+ expect_any_instance_of(Heroploy::Tasks::CheckTaskLib).to receive(:check_pushed).with("my-branch")
8
8
  task.invoke
9
9
  end
10
10
  end
@@ -1,9 +1,9 @@
1
1
  describe "check:remote" do
2
- let(:environment) { build(:env_config, :production) }
2
+ let(:environment) { build(:environment, :production) }
3
3
  include_context "rake"
4
4
 
5
5
  it "invokes :check_remote" do
6
- expect_any_instance_of(Heroploy::CheckTaskLib).to receive(:check_remote).with("production")
6
+ expect_any_instance_of(Heroploy::Tasks::CheckTaskLib).to receive(:check_remote).with("production")
7
7
  task.invoke
8
8
  end
9
9
  end
@@ -1,6 +1,6 @@
1
1
  describe "check:staged" do
2
- let(:production) { build(:env_config, :production) }
3
- let(:staging) { build(:env_config, :staging, remote: "my-staging-remote") }
2
+ let(:production) { build(:environment, :production) }
3
+ let(:staging) { build(:environment, :staging, remote: "my-staging-remote") }
4
4
  let(:environments) { [production, staging] }
5
5
 
6
6
  include_context "rake"
@@ -9,9 +9,9 @@ describe "check:staged" do
9
9
  before { production.checks.staged = 'staging' }
10
10
 
11
11
  it "invokes :check_pushed" do
12
- Heroploy::CheckTaskLib.any_instance.stub(:current_branch).and_return("my-branch")
12
+ Heroploy::Tasks::CheckTaskLib.any_instance.stub(:current_branch).and_return("my-branch")
13
13
 
14
- expect_any_instance_of(Heroploy::CheckTaskLib).to receive(:check_staged).with("my-staging-remote", "my-branch", "staging")
14
+ expect_any_instance_of(Heroploy::Tasks::CheckTaskLib).to receive(:check_staged).with("my-staging-remote", "my-branch", "staging")
15
15
 
16
16
  task.invoke
17
17
  end
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'coveralls'
2
2
  Coveralls.wear! do
3
3
  add_filter '/spec/'
4
+ add_filter 'lib/heroploy/engine.rb'
4
5
  end
5
6
 
6
7
  require 'factory_girl'
@@ -11,11 +12,16 @@ require "generator_spec/matcher"
11
12
 
12
13
  require 'heroploy'
13
14
  require 'heroploy/tasks/deploy_task_lib'
15
+ require 'heroploy/config/deployment_config'
16
+ require 'heroploy/config/environment'
17
+ require 'heroploy/config/environment_checks'
14
18
 
15
19
  require 'support/shell_support'
16
20
  require 'support/shared_contexts/rake'
17
21
  require 'support/shared_contexts/generator'
18
22
 
23
+ require 'support/customer_matchers/environment_matcher'
24
+
19
25
  FactoryGirl.find_definitions
20
26
 
21
27
  TMP_ROOT = Pathname.new(File.expand_path('../tmp', __FILE__))
@@ -26,4 +32,7 @@ RSpec.configure do |config|
26
32
  config.include FactoryGirl::Syntax::Methods
27
33
 
28
34
  config.include ShellSupport
35
+ config.include CustomMatchers
29
36
  end
37
+
38
+
@@ -0,0 +1,36 @@
1
+ module CustomMatchers
2
+ class EnvironmentMatcher
3
+ def initialize(expected_name)
4
+ @expected_name = expected_name
5
+ end
6
+
7
+ def matches_type?
8
+ @actual.is_a?(Heroploy::Config::Environment)
9
+ end
10
+
11
+ def matches_name?
12
+ @actual.name == @expected_name.to_s
13
+ end
14
+
15
+ def matches?(actual)
16
+ @actual = actual
17
+ matches_type? && matches_name?
18
+ end
19
+
20
+ def failure_message_for_should
21
+ if !matches_type?
22
+ "expected type to be Heroploy::Config::Environment"
23
+ elsif !matches_name?
24
+ "expected '#{@actual.name}' to be '#{@expected_name.to_s}'"
25
+ end
26
+ end
27
+ end
28
+
29
+ def an_environment_named(expected_name)
30
+ EnvironmentMatcher.new(expected_name)
31
+ end
32
+
33
+ def be_an_environment_named(expected_name)
34
+ EnvironmentMatcher.new(expected_name)
35
+ end
36
+ end
@@ -11,7 +11,7 @@ shared_context "rake" do
11
11
  elsif defined?(environments)
12
12
  env_name = environments[0].name
13
13
  else
14
- env_name = deploy_config.environments[0].name
14
+ env_name = deployment_config.environments[0].name
15
15
  end
16
16
 
17
17
  "#{env_name}:#{self.class.top_level_description}"
@@ -26,15 +26,15 @@ shared_context "rake" do
26
26
 
27
27
  unless defined?(deploy_config)
28
28
  if defined?(environment)
29
- deploy_config = build(:deploy_config, environments: [environment])
29
+ deployment_config = build(:deployment_config, environments: [environment])
30
30
  elsif defined?(environments)
31
- deploy_config = build(:deploy_config, environments: environments)
31
+ deployment_config = build(:deployment_config, environments: environments)
32
32
  else
33
- deploy_config = build(:deploy_config)
33
+ deployment_config = build(:deployment_config)
34
34
  end
35
35
  end
36
36
 
37
- Heroploy::DeployTaskLib.new(deploy_config)
37
+ Heroploy::Tasks::DeployTaskLib.new(deployment_config)
38
38
 
39
39
  Rake::Task.tasks.each do |task|
40
40
  if task.name != task_name
@@ -1,22 +1,22 @@
1
1
  module ShellSupport
2
2
  def stub_shell
3
- Shell.stub(:eval).and_return("")
4
- Shell.stub(:exec)
3
+ Heroploy::Shell.stub(:eval).and_return("")
4
+ Heroploy::Shell.stub(:exec)
5
5
  end
6
6
 
7
7
  def expect_command(cmd = nil)
8
8
  if cmd.nil?
9
- expect(Shell).to receive(:exec)
9
+ expect(Heroploy::Shell).to receive(:exec)
10
10
  else
11
- expect(Shell).to receive(:exec).with(cmd)
11
+ expect(Heroploy::Shell).to receive(:exec).with(cmd)
12
12
  end
13
13
  end
14
14
 
15
15
  def expect_eval(cmd = nil)
16
16
  if cmd.nil?
17
- expect(Shell).to receive(:eval)
17
+ expect(Heroploy::Shell).to receive(:eval)
18
18
  else
19
- expect(Shell).to receive(:eval).with(cmd)
19
+ expect(Heroploy::Shell).to receive(:eval).with(cmd)
20
20
  end
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: heroploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Brunton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-01 00:00:00.000000000 Z
11
+ date: 2014-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -132,9 +132,9 @@ files:
132
132
  - lib/heroploy/commands/git.rb
133
133
  - lib/heroploy/commands/heroku.rb
134
134
  - lib/heroploy/commands/shell.rb
135
- - lib/heroploy/config/checks_config.rb
136
- - lib/heroploy/config/deploy_config.rb
137
- - lib/heroploy/config/env_config.rb
135
+ - lib/heroploy/config/deployment_config.rb
136
+ - lib/heroploy/config/environment.rb
137
+ - lib/heroploy/config/environment_checks.rb
138
138
  - lib/heroploy/engine.rb
139
139
  - lib/heroploy/tasks/check_task_lib.rb
140
140
  - lib/heroploy/tasks/deploy_task_lib.rb
@@ -147,12 +147,16 @@ files:
147
147
  - spec/lib/heroploy/commands/git_spec.rb
148
148
  - spec/lib/heroploy/commands/heroku_spec.rb
149
149
  - spec/lib/heroploy/commands/shell_spec.rb
150
+ - spec/lib/heroploy/config/deployment_config_spec.rb
151
+ - spec/lib/heroploy/config/environment_checks_spec.rb
152
+ - spec/lib/heroploy/config/environment_spec.rb
150
153
  - spec/lib/heroploy/tasks/check_all_spec.rb
151
154
  - spec/lib/heroploy/tasks/check_branch_spec.rb
152
155
  - spec/lib/heroploy/tasks/check_pushed_spec.rb
153
156
  - spec/lib/heroploy/tasks/check_remote_spec.rb
154
157
  - spec/lib/heroploy/tasks/check_staged_spec.rb
155
158
  - spec/spec_helper.rb
159
+ - spec/support/customer_matchers/environment_matcher.rb
156
160
  - spec/support/helpers/deploy_config_helper.rb
157
161
  - spec/support/shared_contexts/generator.rb
158
162
  - spec/support/shared_contexts/rake.rb
@@ -188,13 +192,18 @@ test_files:
188
192
  - spec/lib/heroploy/commands/git_spec.rb
189
193
  - spec/lib/heroploy/commands/heroku_spec.rb
190
194
  - spec/lib/heroploy/commands/shell_spec.rb
195
+ - spec/lib/heroploy/config/deployment_config_spec.rb
196
+ - spec/lib/heroploy/config/environment_checks_spec.rb
197
+ - spec/lib/heroploy/config/environment_spec.rb
191
198
  - spec/lib/heroploy/tasks/check_all_spec.rb
192
199
  - spec/lib/heroploy/tasks/check_branch_spec.rb
193
200
  - spec/lib/heroploy/tasks/check_pushed_spec.rb
194
201
  - spec/lib/heroploy/tasks/check_remote_spec.rb
195
202
  - spec/lib/heroploy/tasks/check_staged_spec.rb
196
203
  - spec/spec_helper.rb
204
+ - spec/support/customer_matchers/environment_matcher.rb
197
205
  - spec/support/helpers/deploy_config_helper.rb
198
206
  - spec/support/shared_contexts/generator.rb
199
207
  - spec/support/shared_contexts/rake.rb
200
208
  - spec/support/shell_support.rb
209
+ has_rdoc:
@@ -1,16 +0,0 @@
1
- class ChecksConfig
2
- attr_accessor :pushed
3
- attr_accessor :branch
4
- attr_accessor :staged
5
-
6
- def self.parse(attrs)
7
- config = ChecksConfig.new
8
-
9
- attrs ||= {}
10
- config.pushed = attrs['pushed']
11
- config.branch = attrs['branch']
12
- config.staged = attrs['staged'] == true ? 'staging' : attrs['staged']
13
-
14
- config
15
- end
16
- end
@@ -1,24 +0,0 @@
1
- require 'heroploy/config/env_config'
2
-
3
- class DeployConfig
4
- attr_accessor :environments
5
-
6
- def [](env_name)
7
- environments.select{ |env_config| env_config.name == env_name}.first
8
- end
9
-
10
- def self.parse(attrs)
11
- config = DeployConfig.new
12
-
13
- config.environments = []
14
- attrs['environments'].each do |name, attrs|
15
- config.environments << EnvConfig.parse(name, attrs)
16
- end
17
-
18
- config
19
- end
20
-
21
- def self.load
22
- DeployConfig.parse(YAML::load(File.open('config/heroploy.yml')))
23
- end
24
- end
@@ -1,21 +0,0 @@
1
- require 'heroploy/config/checks_config'
2
-
3
- class EnvConfig
4
- attr_accessor :name
5
- attr_accessor :remote
6
- attr_accessor :app
7
- attr_accessor :tag
8
- attr_accessor :checks
9
-
10
- def self.parse(name, attrs)
11
- config = EnvConfig.new
12
-
13
- config.name = name
14
- config.remote = attrs['remote'] || name
15
- config.app = attrs['app']
16
- config.tag = attrs['tag']
17
- config.checks = ChecksConfig.parse(attrs['checks'])
18
-
19
- config
20
- end
21
- end