trooper 0.6.0.alpha2 → 0.6.0.beta

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,27 +11,61 @@ module Trooper
11
11
  attr_reader :name, :description, :config, :block
12
12
  attr_accessor :commands
13
13
 
14
- # expects a name, description and a block
14
+ # Public: Define a new action.
15
+ #
16
+ # name - The name of the action.
17
+ # description - A description of action to be used in the cli output.
18
+ # block - A block containing the tasks to run in this action.
19
+ #
20
+ # Examples
21
+ #
15
22
  # Action.new(:my_action, 'Does great things') { run 'touch file' }
23
+ #
24
+ # Returns a new action object.
16
25
  def initialize(name, description, &block)
17
26
  @name, @description, @config = name, description, {}
18
27
  @commands, @block = [], block
19
28
  end
20
29
 
21
- # eval's the block passed on initialize and returns the command array
30
+ # Public: Eval's the block passed on initialize.
31
+ #
32
+ # configuration - The configuration object to be used for block eval.
33
+ #
34
+ # Examples
35
+ #
36
+ # @action.call(config_object) # => ['touch file']
37
+ #
38
+ # Returns an array of commands(strings).
22
39
  def call(configuration)
23
40
  @config = configuration
24
41
  eval_block(&block)
25
42
  commands
26
43
  end
27
44
  alias :execute :call
28
-
29
- # validates the action
45
+
46
+ # Public: Validates the action object. (NOT WORKING)
47
+ #
48
+ # Examples
49
+ #
50
+ # @action.ok? # => true
51
+ #
52
+ # Returns true.
30
53
  def ok?
31
54
  true
32
55
  end
33
56
 
34
57
  # run is the base run command used by the dsl
58
+
59
+ # Public: Appends command(string) to commands(array).
60
+ #
61
+ # command - A String to be added to the commands array.
62
+ #
63
+ # Examples
64
+ #
65
+ # @action.run 'touch file' # => 'touch file'
66
+ # @action.run '' # => nil
67
+ #
68
+ # Returns the command or nil.
35
69
  def run(command)
36
70
  commands << command if command != ''
37
71
  end
@@ -0,0 +1,34 @@
1
+ require 'trooper/action'
2
+
3
+ module Trooper
4
+ module Actions
5
+
6
+ class PreparePrerequisiteAction < Action
7
+
8
+ def initialize(config = {})
9
+ @name = :prepare_prerequisite
10
+ @description = "Preparing Prerequisites"
11
+ @config = config
12
+ @commands = []
13
+ end
14
+
15
+ def call(configuration)
16
+ @config = configuration
17
+ @commands = []
18
+
19
+ build_commands
20
+ commands
21
+ end
22
+
23
+ private
24
+
25
+ def build_commands
26
+ create_folders trooper_path
27
+ run "echo '#{@name}' >> #{prerequisite_list}"
28
+ run 'echo -e "Prerequisites Prepared"'
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
@@ -24,7 +24,7 @@ module Trooper
24
24
  cd application_path
25
25
  create_folder 'tmp'
26
26
  run 'touch tmp/restart.txt'
27
- run 'echo "Server restarted!"'
27
+ run 'echo -e "Server restarted!"'
28
28
  end
29
29
 
30
30
  end
@@ -0,0 +1,33 @@
1
+ require 'trooper/action'
2
+
3
+ module Trooper
4
+ module Actions
5
+
6
+ class SetupTrooperAction < Action
7
+
8
+ def initialize(config = {})
9
+ @name = :setup_trooper
10
+ @description = "Setup Trooper"
11
+ @config = config
12
+ @commands = []
13
+ end
14
+
15
+ def call(configuration)
16
+ @config = configuration
17
+ @commands = []
18
+
19
+ build_commands
20
+ commands
21
+ end
22
+
23
+ private
24
+
25
+ def build_commands
26
+ create_folders path, trooper_path
27
+ run 'echo -e "Trooper Setup on Server"'
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -3,16 +3,19 @@ require 'trooper/action'
3
3
  require 'trooper/actions/clone_repository_action'
4
4
  require 'trooper/actions/install_gems_action'
5
5
  require 'trooper/actions/migrate_database_action'
6
+ require 'trooper/actions/prepare_prerequisite_action'
6
7
  require 'trooper/actions/restart_server_action'
7
8
  require 'trooper/actions/rollback_migrate_action'
8
9
  require 'trooper/actions/setup_database_action'
10
+ require 'trooper/actions/setup_trooper_action'
9
11
  require 'trooper/actions/update_repository_action'
10
12
 
11
13
  module Trooper
12
14
  module Config
13
15
  module Action
14
16
 
15
- DEFAULT_ACTIONS = [Actions::CloneRepositoryAction, Actions::InstallGemsAction,
17
+ DEFAULT_ACTIONS = [Actions::SetupTrooperAction, Actions::PreparePrerequisiteAction,
18
+ Actions::CloneRepositoryAction, Actions::InstallGemsAction,
16
19
  Actions::MigrateDatabaseAction, Actions::RestartServerAction,
17
20
  Actions::RollbackMigrateAction, Actions::SetupDatabaseAction,
18
21
  Actions::UpdateRepositoryAction]
@@ -0,0 +1,20 @@
1
+ require 'trooper/config/action'
2
+
3
+ module Trooper
4
+ module Config
5
+ module Defaults
6
+ FILE_NAME = "Troopfile"
7
+
8
+ include Trooper::Config::Action
9
+
10
+ def load_defaults!(options = {})
11
+ config[:file_name] = options[:file_name] || FILE_NAME
12
+ config[:environment] = options[:environment] || :production
13
+ config[:ruby_bin_path] = options[:ruby_bin_path] || ""
14
+
15
+ load_default_actions!
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -28,9 +28,14 @@ module Trooper
28
28
  def path(arg)
29
29
  set :application_path => "#{arg}/application"
30
30
  set :trooper_path => "#{arg}/trooper"
31
+ set :prerequisite_list => "#{arg}/trooper/prerequisite_list"
31
32
  set :path => arg
32
33
  end
33
34
 
35
+ def ruby_bin_path(arg)
36
+ set :ruby_bin_path => arg.gsub(/[^\/]$/, '\1/') # /usr/local/bin/
37
+ end
38
+
34
39
  end
35
40
  end
36
41
  end
@@ -4,15 +4,14 @@ require 'trooper/arsenal'
4
4
 
5
5
  require 'trooper/config/environment'
6
6
  require 'trooper/config/strategy'
7
- require 'trooper/config/action'
7
+ require 'trooper/config/defaults'
8
8
 
9
9
  module Trooper
10
10
  class Configuration < Hash
11
- FILE_NAME = "Troopfile"
12
11
 
13
12
  include Trooper::Config::Environment
14
13
  include Trooper::Config::Strategy
15
- include Trooper::Config::Action
14
+ include Trooper::Config::Defaults
16
15
 
17
16
  def self.init
18
17
  gem_dir = File.dirname(__FILE__)
@@ -30,16 +29,14 @@ module Trooper
30
29
  # Configuration.new({:my_override => 'settings'})
31
30
  def initialize(options = {})
32
31
  @loaded = false
33
- @file_name = options[:file_name] || FILE_NAME
34
- self[:environment] = options[:environment] || :production
35
32
 
36
- load_default_actions!
33
+ load_defaults! options
37
34
  load_troopfile! options
38
35
  end
39
36
 
40
37
  # returns a terminal friendly version of the configuration
41
38
  def to_s
42
- self.map {|k,v| "#{k}: #{v}" }.join("\n")
39
+ config.map {|k,v| "#{k}: #{v}" }.join("\n")
43
40
  end
44
41
 
45
42
  # will find and execute the strategy name passed
@@ -51,7 +48,7 @@ module Trooper
51
48
  # a way to set variables that will be available to all actions
52
49
  # set(:my_variable => 'sdsd') # => available as method in an action
53
50
  def set(hash)
54
- self.merge! hash
51
+ config.merge! hash
55
52
  end
56
53
 
57
54
  # returns true if the troopfile was loaded
@@ -61,6 +58,10 @@ module Trooper
61
58
 
62
59
  private
63
60
 
61
+ def config
62
+ self
63
+ end
64
+
64
65
  # loads the troopfile and sets the environment up
65
66
  def load_troopfile!(options)
66
67
  if troopfile?
@@ -70,18 +71,18 @@ module Trooper
70
71
  load_environment!
71
72
  set options
72
73
  else
73
- raise Trooper::NoConfigurationFileError, "No Configuration file (#{@file_name}) can be found!"
74
+ raise Trooper::NoConfigurationFileError, "No Configuration file (#{self[:file_name]}) can be found!"
74
75
  end
75
76
  end
76
77
 
77
78
  # returns the troopfile file object
78
79
  def troopfile
79
- File.open(@file_name)
80
+ File.open(config[:file_name])
80
81
  end
81
82
 
82
83
  # returns true if the troopfile exists
83
84
  def troopfile?
84
- File.exists?(@file_name)
85
+ File.exists?(config[:file_name])
85
86
  end
86
87
 
87
88
  end
@@ -3,12 +3,12 @@ module Trooper
3
3
  module Bundler
4
4
 
5
5
  def bundle_exec(command)
6
- use_bundle = using_bundler? ? "bundle exec " : ""
6
+ use_bundle = using_bundler? ? "#{ruby_bin_path}bundle exec " : ""
7
7
  run use_bundle + command
8
8
  end
9
9
 
10
10
  def bundle_install
11
- run "bundle install --path #{trooper_path}/bundle --deployment --without development test" if using_bundler?
11
+ run "#{ruby_bin_path}bundle install --path #{trooper_path}/bundle --deployment --without development test" if using_bundler?
12
12
  end
13
13
 
14
14
  def rake(command)
@@ -20,6 +20,10 @@ module Trooper
20
20
  def using_bundler?
21
21
  File.exists? "Gemfile"
22
22
  end
23
+
24
+ def ruby_bin_path
25
+ config[:ruby_bin_path] || ""
26
+ end
23
27
 
24
28
  end
25
29
  end
@@ -3,7 +3,13 @@ module Trooper
3
3
  module Rake
4
4
 
5
5
  def rake(command)
6
- run "rake #{command}"
6
+ run "#{ruby_bin_path}rake #{command}"
7
+ end
8
+
9
+ private
10
+
11
+ def ruby_bin_path
12
+ config[:ruby_bin_path] || ""
7
13
  end
8
14
 
9
15
  end
@@ -8,28 +8,32 @@ module Trooper
8
8
  def initialize(name, description, config = {}, &block)
9
9
  @name, @description, @config = name, description, config
10
10
  @run_list = []
11
- eval_block(&block)
11
+ @block = block if block_given?
12
12
  end
13
13
 
14
14
  def execute(config = {})
15
15
  @config = config
16
+
17
+ eval_block
18
+
16
19
  Trooper.logger.debug "Configuration\n#{config}"
17
20
  Trooper.logger.strategy description
18
21
  successful = nil
19
-
22
+
20
23
  runners.each do |runner|
21
24
  begin
22
25
  Trooper.logger.info "\e[4mRunning on #{runner}\n"
23
26
 
24
- run_list.each do |item, name|
25
- self.send("#{item}_execute", runner, name)
27
+ run_list.each do |strategy, type, name|
28
+ commands = build_commands strategy, type, name
29
+ runner_execute! runner, commands if commands
26
30
  end
27
31
 
28
32
  successful = true
29
33
  Trooper.logger.success "\e[4mAll Actions Completed\n"
30
34
  rescue Exception => e
31
35
  Trooper.logger.error "#{e.class.to_s} : #{e.message}\n\n#{e.backtrace.join("\n")}"
32
-
36
+
33
37
  successful = false
34
38
  break #stop commands running on other servers
35
39
  ensure
@@ -40,47 +44,78 @@ module Trooper
40
44
  successful
41
45
  end
42
46
 
47
+ def build_run_list
48
+ eval_block
49
+ run_list
50
+ end
51
+
43
52
  def ok?
44
53
  true
45
54
  end
46
55
 
47
- def call(strategy_name)
48
- if Arsenal.strategies[strategy_name]
49
- Arsenal.strategies[strategy_name].run_list.each do |action|
50
- @run_list << action
56
+ def call(*strategy_names)
57
+ [*strategy_names].each do |strategy_name|
58
+ if Arsenal.strategies[strategy_name]
59
+ Arsenal.strategies[strategy_name].build_run_list.each do |action|
60
+ # strategy_name, type, name
61
+ @run_list << action
62
+ end
51
63
  end
52
- end
64
+ end
65
+ end
66
+
67
+ def prerequisites(*strategy_names)
68
+ unless @run_list.detect { |a| a[2] == :prepare_prerequisite }
69
+ @run_list << [@name, :action, :prepare_prerequisite]
70
+ end
71
+ [*strategy_names].each do |strategy_name|
72
+ if Arsenal.strategies[strategy_name]
73
+ Arsenal.strategies[strategy_name].build_run_list.each do |action|
74
+ # strategy_name, type, name
75
+ @run_list << [action[0], :prerequisite, action[2]]
76
+ end
77
+ end
78
+ end
53
79
  end
54
80
 
55
81
  def actions(*action_names)
56
82
  [*action_names].each do |name|
57
- @run_list << [:action, name]
83
+ # strategy_name, type, name
84
+ @run_list << [self.name, :action, name]
58
85
  end
59
86
  end
60
87
 
61
- def method_missing(method_sym, *arguments, &block)
62
- config[method_sym] || super
63
- end
88
+ def build_commands(strategy_name, type, action_name)
89
+ action = Arsenal.actions[action_name]
64
90
 
65
- private
91
+ if action
92
+ commands = action.call config
66
93
 
67
- def eval_block(&block)
68
- if block_given?
69
- if block.arity == 1
70
- block.call self
94
+ case type
95
+ when :prerequisite
96
+ commands << "echo '#{action.name}' >> #{prerequisite_list}"
97
+ commands << "echo '#{action.description}'"
98
+ commands = "touch #{prerequisite_list}; if grep -vz #{action_name} #{prerequisite_list}; then #{commands.join(' && ')}; else echo 'Already Done'; fi"
99
+ Trooper.logger.action "Prerequisite: #{action.description}"
71
100
  else
72
- instance_eval &block
101
+ Trooper.logger.action action.description
73
102
  end
103
+
104
+ commands
105
+ else
106
+ raise MissingActionError, "Cant find action: #{action_name}"
74
107
  end
75
108
  end
76
109
 
77
- def action_execute(runner, name)
78
- action = Arsenal.actions[name]
110
+ def method_missing(method_sym, *arguments, &block)
111
+ config[method_sym] || super
112
+ end
79
113
 
80
- if action
81
- commands = action.call config
82
- Trooper.logger.action action.description
83
- runner_execute!(runner, commands)
114
+ private
115
+
116
+ def eval_block
117
+ if @block
118
+ instance_eval &@block
84
119
  end
85
120
  end
86
121
 
@@ -1,29 +1,38 @@
1
+ #Basic settings
1
2
  user 'my_user'
2
3
  hosts 'stage.example.com'
4
+ path "/fullpath/to/folder"
3
5
  repository 'git@git.bar.co.uk:whatever.git'
4
- path "/path/to/data/folder"
6
+ # ruby_bin_path "/fullpath/to/ruby/bin/folder" # Define if you have issues with gems
5
7
 
6
- set :my_value => 'something'
8
+ # set :my_value => 'something' # Setting a custom value
7
9
 
8
- env :production do
9
- hosts 'production1.example.com', 'production2.example.com'
10
- set :my_value => 'something_else'
10
+ # Set environment specific settings and or actions
11
+ # env :stage do
12
+ # hosts 'stage.example.com', 'stage.example.com'
13
+ # set :my_value => 'something_else'
11
14
 
12
- action :restart do
13
- run 'touch tmp/restert.txt'
14
- end
15
- end
15
+ # action :my_action do
16
+ # #some action
17
+ # end
18
+ # end
19
+
20
+ # action :my_action do
21
+ # #some action
22
+ # end
16
23
 
17
- action :restart do
18
- run 'touch tmp/restert.txt'
24
+ strategy :setup, 'Setting up Application on the Server' do
25
+ actions :setup_trooper, :clone_repository, :setup_database
19
26
  end
20
27
 
21
28
  strategy :update, 'Update the code base on the server' do
29
+ prerequisites :setup
22
30
  actions :update_repository, :install_gems
23
31
  call :restart
24
32
  end
25
33
 
26
34
  strategy :deploy, 'Full deployment to the server' do
35
+ prerequisites :setup
27
36
  call :update
28
37
  actions :migrate_database
29
38
  call :restart
@@ -3,7 +3,7 @@ module Trooper
3
3
  MAJOR = 0
4
4
  MINOR = 6
5
5
  TINY = 0
6
- PRE = 'alpha2'
6
+ PRE = 'beta'
7
7
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
8
8
  end
9
9
  end
data/lib/trooper.rb CHANGED
@@ -11,6 +11,10 @@ module Trooper
11
11
  class MissingStrategyError < TrooperError
12
12
  end
13
13
 
14
+ # When a acton is not defined
15
+ class MissingActionError < TrooperError
16
+ end
17
+
14
18
  # When a CLI argument is missing or badly formed
15
19
  class CliArgumentError < TrooperError
16
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trooper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0.alpha2
4
+ version: 0.6.0.beta
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-16 00:00:00.000000000 Z
12
+ date: 2012-07-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net-ssh
@@ -168,13 +168,16 @@ files:
168
168
  - lib/trooper/actions/clone_repository_action.rb
169
169
  - lib/trooper/actions/install_gems_action.rb
170
170
  - lib/trooper/actions/migrate_database_action.rb
171
+ - lib/trooper/actions/prepare_prerequisite_action.rb
171
172
  - lib/trooper/actions/restart_server_action.rb
172
173
  - lib/trooper/actions/rollback_migrate_action.rb
173
174
  - lib/trooper/actions/setup_database_action.rb
175
+ - lib/trooper/actions/setup_trooper_action.rb
174
176
  - lib/trooper/actions/update_repository_action.rb
175
177
  - lib/trooper/arsenal.rb
176
178
  - lib/trooper/cli.rb
177
179
  - lib/trooper/config/action.rb
180
+ - lib/trooper/config/defaults.rb
178
181
  - lib/trooper/config/environment.rb
179
182
  - lib/trooper/config/strategy.rb
180
183
  - lib/trooper/configuration.rb
@@ -205,7 +208,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
205
208
  version: '0'
206
209
  segments:
207
210
  - 0
208
- hash: 987069315358731721
211
+ hash: -2382425093214391347
209
212
  required_rubygems_version: !ruby/object:Gem::Requirement
210
213
  none: false
211
214
  requirements: