mina 0.2.0.pre2 → 0.2.0

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.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@ test_env/deploy
3
3
  .rvmrc
4
4
  Gemfile.lock
5
5
  pkg/
6
+ docs
data/HISTORY.md CHANGED
@@ -1,5 +1,5 @@
1
- v0.2.0 - Unreleased
2
- -------------------
1
+ v0.2.0
2
+ ------
3
3
 
4
4
  This release had two pre releases:
5
5
 
@@ -7,6 +7,12 @@ This release had two pre releases:
7
7
  * v0.1.3.pre1 (Jul 13, 2012)
8
8
 
9
9
  ### Fixed:
10
+ * Allow changing `:term_mode` in the setup task. (#51, @alfuken)
11
+ * Prevent `git log` from using a pager. (#42, @tmak)
12
+ * `deploy:cleanup` can now be called in a deploy script. (#50, @dariocravero)
13
+ * Don't invoke bash anymore (!), assume that bash is the shell for the user.
14
+ Fixes Ubuntu 12, and many other things.
15
+ * Fixed `ssh(cmd, return: true)` that used to exit. (#53 from @jpascal)
10
16
  * [pre2] Call ssh with no double use `-t` parameter.
11
17
  * [pre2] Fix Ruby 1.8 compatibility.
12
18
  * [pre2] Fix the "undefined method > for Process::Status" error.
@@ -16,6 +22,13 @@ This release had two pre releases:
16
22
  * [pre1] Doing `rails:assets_precompile` now properly skips asset compilation if not needed. (#25)
17
23
 
18
24
  ### Added:
25
+ * __Added the 'queue!' helper.__
26
+ * Add support for __Whenever__. (#47, @jpascal)
27
+ * Add a new `:environment` task that gets loaded on setup/deploy.
28
+ * __Add explicit support for rbenv/rvm.__ (#5, #39)
29
+ * Implement :'rvm:use[...]'. (#5, #39)
30
+ * Implement :'rbenv:load'. (#5, #39)
31
+ * Revert `rails:optimize_for_3.2` from the pre2 release. (#32)
19
32
  * [pre2] __Optimize git:clone by caching the repository.__ This way, updates are
20
33
  faster because not the entire repo is cloned everytime. (#10)
21
34
  * [pre2] __Show elapsed time that a deploy takes.__
@@ -24,7 +37,7 @@ This release had two pre releases:
24
37
  * [pre2] New `die` helper.
25
38
  * [pre2] New `report_time` helper.
26
39
  * [pre2] New `to_directory` helper. (#35)
27
- * [pre2] Put optional optimizations for Rails 3.2 asset pipeline. (#32)
40
+ * [pre2] Put optional optimizations for Rails 3.2 asset pipeline. (#32) -- reverted
28
41
  * Update sample deploy script:
29
42
  - [pre2] Update default deploy.rb to note :branch.
30
43
  - [pre2] Add `link_shared_paths` to the sample deploy script.
@@ -33,6 +46,15 @@ This release had two pre releases:
33
46
  * [pre1] Make asset paths configurable using the `asset_paths` setting.
34
47
 
35
48
  ### Changed:
49
+ * Force removal of shared path destinations before linking with
50
+ `deploy:link_shared_paths`. Fixes symlinking of `log/` in Rails projects.
51
+ * __Rails: speed up default asset compilation a bit by invoking
52
+ `assets:precompile` with `RAILS_GROUPS=assets`.__
53
+ * Add helpful error message when there is a problem with
54
+ deploy.rb or a custom Rakefile. (#37, @sge-jesse-adams)
55
+ * Update the default deploy.rb to add notes about 'mina setup' customizations.
56
+ * Make `mina run`, `mina rake`, `mina console` use the new `:environment` task.
57
+ * Allow calling `die` without arguments.
36
58
  * [pre2] __Improve output of `mina init`.__
37
59
  * [pre2] Prettier output for `mina setup`. Also, show a better error message for it.
38
60
  * [pre1] Refactor pretty printing to be simpler, cleaner, and extensible.
data/Rakefile CHANGED
@@ -1,9 +1,20 @@
1
1
  require 'bundler'
2
2
  require 'bundler/gem_tasks'
3
3
 
4
+ github = ENV['github'] || 'nadarei/mina'
5
+
4
6
  task :spec do
5
7
  system "rm Gemfile.lock; sh -c 'rake=0.8 bundle exec rspec'"
6
8
  system "rm Gemfile.lock; sh -c 'rake=0.9 bundle exec rspec'"
7
9
  end
8
10
 
11
+ task :docs do
12
+ files = ['manual/index.md', 'manual/modules.md', 'HISTORY.md'] + Dir['lib/**/*.rb']
13
+ system "lidoc #{files.join ' '} -o docs --github #{github}"
14
+ end
15
+
16
+ task :'docs:deploy' => :docs do
17
+ system "git-update-ghpages #{github} -i docs -p docs"
18
+ end
19
+
9
20
  task :default => :spec
data/bin/mina CHANGED
@@ -42,7 +42,12 @@ Rake.application.instance_eval do
42
42
  require 'mina/rake'
43
43
 
44
44
  # Allow running without a Rakefile
45
- load_rakefile if have_rakefile || custom_rakefile
45
+ begin
46
+ load_rakefile if have_rakefile || custom_rakefile
47
+ rescue Exception
48
+ puts "Error loading Rakefile!"
49
+ raise "There may be a problem with config/deploy.rb and/or Rakefile"
50
+ end
46
51
 
47
52
  # Run tasks
48
53
  top_level
@@ -1,13 +1,8 @@
1
- # For help in making your deploy script, see the Mina documentation:
2
- #
3
- # - http://nadarei.co/mina
4
- # - http://nadarei.co/mina/tasks
5
- # - http://nadarei.co/mina/settings
6
- # - http://nadarei.co/mina/helpers
7
-
8
1
  require 'mina/bundler'
9
2
  require 'mina/rails'
10
3
  require 'mina/git'
4
+ # require 'mina/rbenv' # for rbenv support. (http://rbenv.org)
5
+ # require 'mina/rvm' # for rvm support. (http://rvm.io)
11
6
 
12
7
  # Basic settings:
13
8
  # domain - The hostname to SSH to.
@@ -22,19 +17,40 @@ set :branch, 'master'
22
17
 
23
18
  # Manually create these paths in shared/ (eg: shared/config/database.yml) in your server.
24
19
  # They will be linked in the 'deploy:link_shared_paths' step.
25
- set :shared_paths, ['config/database.yml']
20
+ set :shared_paths, ['config/database.yml', 'log']
26
21
 
27
22
  # Optional settings:
28
23
  # set :user, 'foobar' # Username in the server to SSH to.
29
24
  # set :port, '30000' # SSH port number.
30
25
 
26
+ # This task is the environment that is loaded for most commands, such as
27
+ # `mina deploy` or `mina rake`.
28
+ task :environment do
29
+ # If you're using rbenv, use this to load the rbenv environment.
30
+ # Be sure to commit your .rbenv-version to your repository.
31
+ # invoke :'rbenv:load'
32
+
33
+ # For those using RVM, use this to load an RVM version@gemset.
34
+ # invoke :'rvm:use[ruby-1.9.3-p125@default]'
35
+ end
36
+
37
+ # Put any custom mkdir's in here for when `mina setup` is ran.
38
+ # For Rails apps, we'll make some of the shared paths that are shared between
39
+ # all releases.
40
+ task :setup => :environment do
41
+ queue! %[mkdir -p "#{deploy_to}/shared/log"]
42
+ queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/log"]
43
+
44
+ queue! %[mkdir -p "#{deploy_to}/shared/config"]
45
+ queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/config"]
46
+
47
+ queue! %[touch "#{deploy_to}/shared/config/database.yml"]
48
+ queue %[-----> Be sure to edit 'shared/config/database.yml'.]
49
+ end
50
+
31
51
  desc "Deploys the current version to the server."
32
- task :deploy do
52
+ task :deploy => :environment do
33
53
  deploy do
34
- # This makes asset compilation faster in Rails 3.2 -- remove this for other
35
- # Rails versions.
36
- invoke :'rails:optimize_for_3.2'
37
-
38
54
  # Put things that will set up an empty directory into a fully set-up
39
55
  # instance of your project.
40
56
  invoke :'git:clone'
@@ -48,3 +64,11 @@ task :deploy do
48
64
  end
49
65
  end
50
66
  end
67
+
68
+ # For help in making your deploy script, see the Mina documentation:
69
+ #
70
+ # - http://nadarei.co/mina
71
+ # - http://nadarei.co/mina/tasks
72
+ # - http://nadarei.co/mina/settings
73
+ # - http://nadarei.co/mina/helpers
74
+
@@ -1,9 +1,36 @@
1
+ # # Modules: Bundler
2
+ # Adds settings and tasks for managing Ruby Bundler.
3
+ #
4
+ # require 'mina/bundler'
1
5
 
2
- settings.bundle_bin ||= 'bundle'
3
- settings.bundle_path ||= './vendor/bundle'
4
- settings.bundle_options ||= lambda { %{--without development:test --path "#{bundle_path}" --binstubs bin/ --deployment} }
6
+ # ## Settings
7
+ # Any and all of these settings can be overriden in your `deploy.rb`.
8
+
9
+ # ### bundle_bin
10
+ # Sets the bundle path.
11
+
12
+ set_default :bundle_bin, 'bundle'
13
+
14
+ # ### bundle_path
15
+ # Sets the path to where the gems are expected to be.
16
+ #
17
+ # This path will be symlinked to `./shared/bundle` so that the gems cache will
18
+ # be shared between all releases.
19
+
20
+ set_default :bundle_path, './vendor/bundle'
21
+
22
+ # ### bundle_options
23
+ # Sets the options for installing gems via Bundler.
24
+
25
+ set_default :bundle_options, lambda { %{--without development:test --path "#{bundle_path}" --binstubs bin/ --deployment} }
26
+
27
+ # ## Deploy tasks
28
+ # These tasks are meant to be invoked inside deploy scripts, not invoked on
29
+ # their own.
5
30
 
6
31
  namespace :bundle do
32
+ # ### bundle:install
33
+ # Installs gems.
7
34
  desc "Install gem dependencies using Bundler."
8
35
  task :install do
9
36
  queue %{
@@ -1,8 +1,25 @@
1
+ # # Modules: Default
2
+ # This module is loaded when invoking `mina` with or without a project.
3
+
1
4
  set_default :bash_options, '-i'
2
5
 
3
- # Default tasks here
6
+ # ## Tasks
7
+ # Any and all of these settings can be overriden in your `deploy.rb`.
8
+
9
+ # ### environment
10
+ # Make the `:environment` task exist by default. This is meant to be overridden
11
+ # by users.
12
+
13
+ task :environment do
14
+ end
15
+
16
+ # ### init
17
+ # Initializes a new Mina project.
18
+ #
19
+ # $ mina init
20
+
4
21
  desc "Creates a sample config file."
5
- task :init do
22
+ task :init => :environment do
6
23
  name = Rake.application.name
7
24
  config_file = Rake.application.rakefile
8
25
 
@@ -63,6 +80,9 @@ end
63
80
 
64
81
  extend HelpHelpers
65
82
 
83
+ # ### help
84
+ # Shows the help screen.
85
+
66
86
  desc "Show help."
67
87
  task :help do
68
88
  name = Rake.application.name
@@ -93,6 +113,11 @@ task :help do
93
113
  puts "for more information."
94
114
  end
95
115
 
116
+ # ### tasks
117
+ # Display all tasks in a nice table.
118
+ #
119
+ # $ mina tasks
120
+
96
121
  desc "Show all tasks."
97
122
  task :tasks do
98
123
  show_task_help :full => true
@@ -1,3 +1,9 @@
1
+ # # Modules: Deployment
2
+ # This module is automatically loaded for all Mina projects.
3
+
4
+ # ## Settings
5
+ # Any and all of these settings can be overriden in your `deploy.rb`.
6
+
1
7
  set_default :releases_path, "releases"
2
8
  set_default :shared_path, "shared"
3
9
  set_default :current_path, "current"
@@ -5,12 +11,26 @@ set_default :lock_file, "deploy.lock"
5
11
  set_default :keep_releases, 5
6
12
 
7
13
  namespace :deploy do
14
+ # ## Tasks
15
+
16
+ # ### deploy:force_unlock
17
+ # Forces a deploy unlock by deleting the lock file.
18
+ #
19
+ # $ mina deploy:force_unlock
20
+ #
21
+ # You can also combine that task with `deploy`:
22
+ #
23
+ # $ mina deploy:force_unlock deploy
24
+
8
25
  desc "Forces a deploy unlock."
9
26
  task :force_unlock do
10
27
  queue %{echo "-----> Unlocking"}
11
28
  queue echo_cmd %{rm -f "#{deploy_to}/#{lock_file}"}
12
29
  end
13
30
 
31
+ # ### deploy:link_shared_paths
32
+ # Links the shared paths in the `shared_paths` setting.
33
+
14
34
  desc "Links paths set in :shared_paths."
15
35
  task :link_shared_paths do
16
36
  dirs = settings.shared_paths!.map { |file| File.dirname("./#{file}") }.uniq
@@ -20,31 +40,43 @@ namespace :deploy do
20
40
  end
21
41
 
22
42
  cmds += shared_paths.map do |file|
23
- echo_cmd %{ln -s "#{deploy_to}/#{shared_path}/#{file}" "./#{file}"}
43
+ [
44
+ echo_cmd(%{rm -rf "./#{file}"}),
45
+ echo_cmd(%{ln -s "#{deploy_to}/#{shared_path}/#{file}" "./#{file}"})
46
+ ]
24
47
  end
25
48
 
26
49
  queue %{
27
50
  echo "-----> Symlinking shared paths"
28
- #{cmds.join(" &&\n")}
51
+ #{cmds.flatten.join(" &&\n")}
29
52
  }
30
53
  end
31
54
 
32
- desc "Clean up old releases. By default, the last 5 releases are kept on
33
- each server (though you can change this with the keep_releases setting).
34
- All other deployed revisions are removed from the servers."
55
+ # ### deploy:cleanup
56
+ # Cleans up old releases.
57
+ #
58
+ # By default, the last 5 releases are kept on each server (though you can
59
+ # change this with the keep_releases setting). All other deployed revisions
60
+ # are removed from the servers."
61
+
62
+ desc "Clean up old releases."
35
63
  task :cleanup do
36
- queue %{echo "-----> Cleaning up old releases (keeping #{keep_releases!})"}
37
- queue echo_cmd %{cd "#{deploy_to!}" || exit 15}
38
- queue echo_cmd %{cd "#{releases_path!}" || exit 16}
39
- queue echo_cmd %{count=`ls -1d [0-9]* | sort -rn | wc -l`}
40
- queue echo_cmd %{remove=$((count > 5 ? count - #{keep_releases} : 0))}
41
- queue echo_cmd %{ls -1d [0-9]* | sort -rn | tail -n $remove | xargs rm -rf {}}
64
+ queue %{
65
+ echo "-----> Cleaning up old releases (keeping #{keep_releases!})"
66
+ #{echo_cmd %{cd "#{deploy_to!}/#{releases_path!}" || exit 15}}
67
+ #{echo_cmd %{count=`ls -1d [0-9]* | sort -rn | wc -l`}}
68
+ #{echo_cmd %{remove=$((count > 5 ? count - #{keep_releases} : 0))}}
69
+ #{echo_cmd %{ls -1d [0-9]* | sort -rn | tail -n $remove | xargs rm -rf {}}}
70
+ }
42
71
  end
43
72
  end
44
73
 
74
+ # ### setup
75
+ # Sets up a site's directory structure.
76
+
45
77
  desc "Sets up a site."
46
78
  task :setup do
47
- set :term_mode, :pretty
79
+ set_default :term_mode, :pretty
48
80
 
49
81
  settings.deploy_to!
50
82
 
@@ -73,8 +105,13 @@ task :setup do
73
105
  }
74
106
  end
75
107
 
108
+ # ### run[]
109
+ # Runs a command on a server.
110
+ #
111
+ # $ mina run[tail -f logs.txt]
112
+
76
113
  desc "Runs a command in the server."
77
- task :run, :command do |t, args|
114
+ task :run, [:command] => [:environment] do |t, args|
78
115
  command = args[:command]
79
116
  unless command
80
117
  puts %[You need to provide a command. Try: mina "run[ls -la]"]
@@ -1,7 +1,9 @@
1
+ # # Helpers: Deploy helpers
2
+ # Helpers for deployment.
1
3
  module Mina
2
- # Helpers for deployment
3
4
  module DeployHelpers
4
- # Wraps the things inside it in a deploy script and queues it.
5
+ # ### deploy
6
+ # Wraps the things inside it in a deploy script and queues it.
5
7
  # This generates a script using deploy_script and queues it.
6
8
  #
7
9
  # Returns nothing.
@@ -10,6 +12,7 @@ module Mina
10
12
  queue deploy_script(&blk)
11
13
  end
12
14
 
15
+ # ### deploy_script
13
16
  # Wraps the things inside it in a deploy script.
14
17
  #
15
18
  # script = deploy_script do
@@ -1,6 +1,23 @@
1
- settings.branch ||= "master"
1
+ # # Modules: Git
2
+ # Adds settings and tasks related to managing Git.
3
+ #
4
+ # require 'mina/git'
5
+
6
+ # ## Settings
7
+ # Any and all of these settings can be overriden in your `deploy.rb`.
8
+
9
+ # ### branch
10
+ # Sets the branch to be deployed.
11
+
12
+ set_default :branch, "master"
2
13
 
3
14
  namespace :git do
15
+ # ## Deploy tasks
16
+ # These tasks are meant to be invoked inside deploy scripts, not invoked on
17
+ # their own.
18
+
19
+ # ### git:clone
20
+ # Clones the Git repository. Meant to be used inside a deploy script.
4
21
  desc "Clones the Git repository to the release path."
5
22
  task :clone do
6
23
  if revision?
@@ -32,7 +49,7 @@ namespace :git do
32
49
  status = %[
33
50
  echo "-----> Using this git commit" &&
34
51
  echo &&
35
- #{echo_cmd %[git log --format="%aN (%h):%n> %s" -n 1]} &&
52
+ #{echo_cmd %[git --no-pager log --format="%aN (%h):%n> %s" -n 1]} &&
36
53
  #{echo_cmd %[rm -rf .git]} &&
37
54
  echo
38
55
  ]
@@ -1,7 +1,8 @@
1
+ # # Helpers: Default helpers
1
2
  module Mina
2
- # Helpers
3
3
  module Helpers
4
4
 
5
+ # ### invoke
5
6
  # Invokes another Rake task.
6
7
  #
7
8
  # Invokes the task given in `task`. Returns nothing.
@@ -13,6 +14,7 @@ module Mina
13
14
  Rake.application.invoke_task task
14
15
  end
15
16
 
17
+ # ### erb
16
18
  # Evaluates an ERB block in the current scope and returns a string.
17
19
  #
18
20
  # a = 1
@@ -31,6 +33,7 @@ module Mina
31
33
  erb.result b
32
34
  end
33
35
 
36
+ # ### run!
34
37
  # SSHs into the host and runs the code that has been queued.
35
38
  #
36
39
  # This is already automatically invoked before Rake exits to run all
@@ -45,6 +48,7 @@ module Mina
45
48
  report_time { ssh commands(:default) }
46
49
  end
47
50
 
51
+ # ### report_time
48
52
  # Report time elapsed in the block.
49
53
  # Returns the output of the block.
50
54
  def report_time(&blk)
@@ -53,6 +57,7 @@ module Mina
53
57
  output
54
58
  end
55
59
 
60
+ # ### measure
56
61
  # Measures the time (in ms) a block takes.
57
62
  # Returns a [time, output] tuple.
58
63
  def measure(&blk)
@@ -61,14 +66,19 @@ module Mina
61
66
  [(Time.now - t).to_i, output]
62
67
  end
63
68
 
69
+ # ## SSH helpers
70
+ # You don't need to invoke these helpers, they're already invoked automatically.
71
+
72
+ # ### ssh
64
73
  # Executes a command via SSH.
65
74
  #
66
75
  # Returns nothing usually, but if `{ return: true }` is given, returns the
67
76
  # STDOUT output of the SSH session.
68
77
  #
69
- # options - Hash of options.
70
- # :pretty - Prettify the output.
71
- # :return - If set to true, returns the output.
78
+ # `options` is a hash of options:
79
+ #
80
+ # - `:pretty` - Prettify the output if true.
81
+ # - `:return` - If set to true, returns the output.
72
82
  #
73
83
  # Example
74
84
  #
@@ -80,10 +90,10 @@ module Mina
80
90
  require 'shellwords'
81
91
 
82
92
  result = 0
83
- script = Shellwords.escape("true;"+cmd)
93
+ script = Shellwords.escape(cmd)
84
94
 
85
95
  if options[:return] == true
86
- result = `#{ssh_command} -- bash -c #{script}`
96
+ result = `#{ssh_command} -- #{script}`
87
97
 
88
98
  elsif simulate_mode?
89
99
  str = "Executing the following via '#{ssh_command}':"
@@ -94,7 +104,7 @@ module Mina
94
104
  puts cmd
95
105
 
96
106
  else
97
- code = "#{ssh_command} -- bash #{bash_options} -c #{script}"
107
+ code = "#{ssh_command} -- #{script}"
98
108
  if settings.term_mode == :pretty
99
109
  result = pretty_system(code)
100
110
  elsif settings.term_mode == :exec
@@ -105,24 +115,11 @@ module Mina
105
115
  end
106
116
  end
107
117
 
108
- die result if result > 0
118
+ die result if result.is_a? Fixnum && result > 0
109
119
  result
110
120
  end
111
121
 
112
- # Exits with a nice looking message.
113
- # Returns nothing.
114
- #
115
- # die 2
116
- # die 2, "Tests failed"
117
- #
118
- def die(code, msg=null)
119
- str = "Failed with status #{code}"
120
- str += " (#{msg})" if msg
121
- err = Failed.new(str)
122
- err.exitstatus = code
123
- raise err
124
- end
125
-
122
+ # ### ssh_command
126
123
  # Returns the SSH command to be executed.
127
124
  #
128
125
  # set :domain, 'foo.com'
@@ -140,6 +137,42 @@ module Mina
140
137
  "ssh #{args}"
141
138
  end
142
139
 
140
+ # ### mina_cleanup
141
+ # __Internal:__ Invoked when Rake exits.
142
+ #
143
+ # Returns nothing.
144
+ #
145
+ def mina_cleanup!
146
+ run! if commands.any?
147
+ end
148
+
149
+ # ## Errors
150
+
151
+ # ### die
152
+ # Exits with a nice looking message.
153
+ # Returns nothing.
154
+ #
155
+ # die 2
156
+ # die 2, "Tests failed"
157
+ #
158
+ def die(code=1, msg=null)
159
+ str = "Failed with status #{code}"
160
+ str += " (#{msg})" if msg
161
+ err = Failed.new(str)
162
+ err.exitstatus = code
163
+ raise err
164
+ end
165
+
166
+ # ### error
167
+ # __Internal:__ Prints to stdout.
168
+ # Consider using `print_error` instead.
169
+ def error(str)
170
+ $stderr.write "#{str}\n"
171
+ end
172
+
173
+ # ## Queueing
174
+
175
+ # ### queue
143
176
  # Queues code to be ran.
144
177
  #
145
178
  # This queues code to be ran to the current code bucket (defaults to `:default`).
@@ -157,30 +190,35 @@ module Mina
157
190
  commands(@to) << unindent(code)
158
191
  end
159
192
 
160
- # Internal: Normalizes indentation on a given string.
193
+ # ### queue!
194
+ # Shortcut for `queue`ing a command that shows up in verbose mode.
195
+
196
+ def queue!(code)
197
+ queue echo_cmd(code)
198
+ end
199
+
200
+ # ### echo_cmd
201
+ # Converts a bash command to a command that echoes before execution.
202
+ # Used to show commands in verbose mode. This does nothing unless verbose mode is on.
161
203
  #
162
- # Returns the normalized string without extraneous indentation.
204
+ # Returns a string of the compound bash command, typically in the format of
205
+ # `echo xx && xx`. However, if `verbose_mode?` is false, it returns the
206
+ # input string unharmed.
163
207
  #
164
- # puts unindent %{
165
- # Hello
166
- # There
167
- # }
168
- # # Output:
169
- # # Hello
170
- # # There
208
+ # echo_cmd("ln -nfs releases/2 current")
209
+ # #=> echo "$ ln -nfs releases/2 current" && ln -nfs releases/2 current
171
210
  #
172
- def unindent(code)
173
- if code =~ /^\n([ \t]+)/
174
- code = code.gsub(/^#{$1}/, '')
211
+ def echo_cmd(str)
212
+ if verbose_mode?
213
+ "echo #{Shellwords.escape("$ " + str)} &&\n#{str}"
214
+ else
215
+ str
175
216
  end
176
-
177
- code.strip
178
217
  end
179
218
 
180
- def reindent(n, code)
181
- indent n, unindent(code)
182
- end
219
+ # ## Commands
183
220
 
221
+ # ### commands
184
222
  # Returns an array of queued code strings.
185
223
  #
186
224
  # You may give an optional `aspect`.
@@ -204,20 +242,21 @@ module Mina
204
242
  end)[aspect]
205
243
  end
206
244
 
207
- # Starts a new block where new #commands are collected.
245
+ # ### isolate
246
+ # Starts a new block where new `commands` are collected.
208
247
  #
209
248
  # Returns nothing.
210
249
  #
211
- # queue "sudo restart"
212
- # queue "true"
213
- # commands.should == ['sudo restart', 'true']
250
+ # queue "sudo restart"
251
+ # queue "true"
252
+ # commands.should == ['sudo restart', 'true']
214
253
  #
215
- # isolate do
216
- # queue "reload"
217
- # commands.should == ['reload']
218
- # end
254
+ # isolate do
255
+ # queue "reload"
256
+ # commands.should == ['reload']
257
+ # end
219
258
  #
220
- # commands.should == ['sudo restart', 'true']
259
+ # commands.should == ['sudo restart', 'true']
221
260
  #
222
261
  def isolate(&blk)
223
262
  old, @commands = @commands, nil
@@ -226,6 +265,7 @@ module Mina
226
265
  result
227
266
  end
228
267
 
268
+ # ### in_directory
229
269
  # Starts a new block where #commands are collected, to be executed inside `path`.
230
270
  #
231
271
  # Returns nothing.
@@ -263,6 +303,9 @@ module Mina
263
303
  @to = old
264
304
  end
265
305
 
306
+ # ## Settings helpers
307
+
308
+ # ### set
266
309
  # Sets settings.
267
310
  # Sets given symbol `key` to value in `value`.
268
311
  #
@@ -274,6 +317,7 @@ module Mina
274
317
  settings.send :"#{key}=", value
275
318
  end
276
319
 
320
+ # ### set_default
277
321
  # Sets default settings.
278
322
  # Sets given symbol `key` to value in `value` only if the key isn't set yet.
279
323
  #
@@ -291,9 +335,11 @@ module Mina
291
335
  settings.send :"#{key}=", value unless settings.send(:"#{key}?")
292
336
  end
293
337
 
338
+ # ### settings
294
339
  # Accesses the settings hash.
295
340
  #
296
341
  # set :domain, 'kickflip.me'
342
+ #
297
343
  # settings.domain #=> 'kickflip.me'
298
344
  # domain #=> 'kickflip.me'
299
345
  #
@@ -301,6 +347,7 @@ module Mina
301
347
  @settings ||= Settings.new
302
348
  end
303
349
 
350
+ # ### method_missing
304
351
  # Hook to get settings.
305
352
  # See #settings for an explanation.
306
353
  #
@@ -310,40 +357,9 @@ module Mina
310
357
  settings.send meth, *args
311
358
  end
312
359
 
313
- def indent(count, str)
314
- str.gsub(/^/, " "*count)
315
- end
316
-
317
- def error(str)
318
- $stderr.write "#{str}\n"
319
- end
320
-
321
- # Converts a bash command to a command that echoes before execution.
322
- # Used to show commands in verbose mode. This does nothing unless verbose mode is on.
323
- #
324
- # Returns a string of the compound bash command, typically in the format of
325
- # `echo xx && xx`. However, if `verbose_mode?` is false, it returns the
326
- # input string unharmed.
327
- #
328
- # echo_cmd("ln -nfs releases/2 current")
329
- # #=> echo "$ ln -nfs releases/2 current" && ln -nfs releases/2 current
330
- #
331
- def echo_cmd(str)
332
- if verbose_mode?
333
- "echo #{("$ " + str).inspect} &&\n#{str}"
334
- else
335
- str
336
- end
337
- end
338
-
339
- # Internal: Invoked when Rake exits.
340
- #
341
- # Returns nothing.
342
- #
343
- def mina_cleanup!
344
- run! if commands.any?
345
- end
360
+ # ## Command line mode helpers
346
361
 
362
+ # ### verbose_mode?
347
363
  # Checks if Rake was invoked with --verbose.
348
364
  #
349
365
  # Returns true or false.
@@ -358,6 +374,7 @@ module Mina
358
374
  end
359
375
  end
360
376
 
377
+ # ### simulate_mode?
361
378
  # Checks if Rake was invoked with --simulate.
362
379
  #
363
380
  # Returns true or false.
@@ -365,5 +382,41 @@ module Mina
365
382
  def simulate_mode?
366
383
  !! ENV['simulate']
367
384
  end
385
+
386
+ # ## Internal helpers
387
+
388
+ # ### indent
389
+ # Indents a given code block with `count` spaces before it.
390
+ def indent(count, str)
391
+ str.gsub(/^/, " "*count)
392
+ end
393
+
394
+ # ### unindent
395
+ # __Internal:__ Normalizes indentation on a given string.
396
+ #
397
+ # Returns the normalized string without extraneous indentation.
398
+ #
399
+ # puts unindent %{
400
+ # Hello
401
+ # There
402
+ # }
403
+ # # Output:
404
+ # # Hello
405
+ # # There
406
+ #
407
+ def unindent(code)
408
+ if code =~ /^\n([ \t]+)/
409
+ code = code.gsub(/^#{$1}/, '')
410
+ end
411
+
412
+ code.strip
413
+ end
414
+
415
+ # ### reindent
416
+ # Resets the indentation on a given code block.
417
+ def reindent(n, code)
418
+ indent n, unindent(code)
419
+ end
420
+
368
421
  end
369
422
  end
@@ -1,35 +1,49 @@
1
+ # # Helpers: Output helpers
2
+ # Protip! make a module that overrides these settings, then use `extend YourModule`
3
+ # to make your own pretty printing thing.
1
4
  module Mina
2
5
  module OutputHelpers
3
- # Protip! make a module that overrides these settings, then use `extend YourModule`
4
- # to make your own pretty printing thing.
6
+
7
+ # ### print_status
8
+ # Prints a status message. (`----->`)
5
9
  def print_status(msg)
6
10
  puts "" if verbose_mode?
7
11
  puts "#{color('----->', 32)} #{msg}"
8
12
  end
9
13
 
14
+ # ### print_error
15
+ # Prints an error message (header).
10
16
  def print_error(msg)
11
17
  puts " #{color("!", 33)} #{color(msg, 31)}"
12
18
  end
13
19
 
20
+ # ### print_stderr
21
+ # Prints an error message (body), or prints stderr output.
14
22
  def print_stderr(msg)
15
23
  puts " #{color(msg, 31)}"
16
24
  end
17
25
 
26
+ # ### print_command
27
+ # Prints a command.
18
28
  def print_command(msg)
19
29
  puts " #{color("$", 32)} #{color(msg, 32)}"
20
30
  end
21
31
 
32
+ # ### print_stdout
33
+ # Prints a normal message.
22
34
  def print_stdout(msg)
23
35
  puts " #{msg}"
24
36
  end
25
37
 
26
- # Internal: Colorizes a string.
38
+ # ### color
39
+ # Colorizes a string.
27
40
  # Returns the string `str` with the color `c`.
28
41
  def color(str, c)
29
42
  ENV['NO_COLOR'] ? str : "\033[#{c}m#{str}\033[0m"
30
43
  end
31
44
 
32
- # Internal: Prints a string by delegating it to the proper output helper.
45
+ # ### print_str
46
+ # Prints a string by delegating it to the proper output helper.
33
47
  #
34
48
  # It takes an input with text and prints them nicely. The text block can
35
49
  # have statuses (prefixed with `-----> `), errors (prefixed with `! `),
@@ -55,7 +69,8 @@ module Mina
55
69
  end
56
70
  end
57
71
 
58
- # Internal: Works like `system`, but indents and puts color.
72
+ # ### pretty_system
73
+ # __Internal:__ Works like `system`, but indents and puts color.
59
74
  #
60
75
  # Returns the exit code in integer form.
61
76
  #
@@ -1,33 +1,65 @@
1
+ # # Modules: Rails
2
+ # Adds settings and tasks for managing Rails projects.
3
+ #
4
+ # require 'mina/rails'
5
+
1
6
  require 'mina/bundler'
2
7
 
3
- settings.rails_env ||= 'production'
8
+ # ## Settings
9
+ # Any and all of these settings can be overriden in your `deploy.rb`.
10
+
11
+ # ### rails_env
12
+ # Sets the Rails environment for `rake` and `rails` commands.
13
+ #
14
+ # Note that changing this will NOT change the environment that your application
15
+ # is ran in.
16
+ set_default :rails_env, 'production'
17
+
18
+ # ### bundle_prefix
19
+ # Prefix for Bundler commands.
4
20
  # TODO: This should be lambda
5
- settings.bundle_prefix ||= lambda { %{RAILS_ENV="#{rails_env}" #{bundle_bin} exec} }
6
- settings.rake ||= lambda { %{#{bundle_prefix} rake} }
7
- settings.rails ||= lambda { %{#{bundle_prefix} rails} }
8
- settings.asset_paths ||= ['vendor/assets/', 'app/assets/']
9
- settings.rake_assets_precompile ||= lambda { "#{rake} assets:precompile" }
10
-
11
- desc "Makes Rails 3.2 deploys faster."
12
- task :'rails:optimize_for_3.2' do
13
- # This is 100% faster in Rails 3.2 because it skips re-invoking the
14
- # Rake+Rails environment twice, and reuses the compilation cache for
15
- # generating digest and non-digest assets. See:
16
- # https://github.com/rails/rails/blob/3-2-stable/actionpack/lib/sprockets/assets.rake
17
- settings.rake_assets_precompile = lambda {
18
- "#{rake} assets:precompile:primary assets:precompile:nondigest RAILS_ENV=production RAILS_GROUPS=assets"
19
- }
20
-
21
- # A safer, but slower (and still faster than default) version would be the
22
- # one below. This will respect your config.assets.digest setting.
23
- # settings.rake_assets_precompile = lambda {
24
- # "#{rake} assets:precompile:all RAILS_ENV=production RAILS_GROUPS=assets"
25
- # }
26
- end
21
+
22
+ set_default :bundle_prefix, lambda { %{RAILS_ENV="#{rails_env}" #{bundle_bin} exec} }
23
+
24
+ # ### rake
25
+ # The prefix for `rake` commands. Use like so:
26
+ #
27
+ # queue "#{rake} db:migrate"
28
+
29
+ set_default :rake, lambda { %{#{bundle_prefix} rake} }
30
+
31
+ # ### rails
32
+ # The prefix for `rails` commands. Use like so:
33
+ #
34
+ # queue "#{rails} console"
35
+
36
+ set_default :rails, lambda { %{#{bundle_prefix} rails} }
37
+
38
+ # ### asset_paths
39
+ # The paths to be checked.
40
+ #
41
+ # Whenever assets are compiled, the asset files are checked if they have
42
+ # changed from the previous release.
43
+ #
44
+ # If they're unchanged, compiled assets will simply be copied over to the new
45
+ # release.
46
+ #
47
+ # Override this if you have custom asset paths declared in your Rails's
48
+ # `config.assets.paths` setting.
49
+
50
+ set_default :asset_paths, ['vendor/assets/', 'app/assets/']
51
+
52
+ # ### rake_assets_precompile
53
+ # The command to invoke when precompiling assets.
54
+ # Override me if you like.
55
+
56
+ settings.rake_assets_precompile ||= lambda { "#{rake} assets:precompile RAILS_GROUPS=assets" }
57
+
58
+ # ----
27
59
 
28
60
  # Macro used later by :rails, :rake, etc
29
61
  make_run_task = lambda { |name, sample_args|
30
- task name, :arguments do |t, args|
62
+ task name, [:arguments] => :environment do |t, args|
31
63
  arguments = args[:arguments]
32
64
  command = send name
33
65
  unless command
@@ -61,18 +93,41 @@ def check_for_changes_script(options={})
61
93
  ]
62
94
  end
63
95
 
96
+ # ## Command-line tasks
97
+ # These tasks can be invoked in the command line.
98
+
99
+ # ### rails[]
100
+ # Invokes a rails command.
101
+ #
102
+ # $ mina rails[console]
103
+
64
104
  desc "Execute a Rails command in the current deploy."
65
105
  make_run_task[:rails, 'console']
66
106
 
107
+ # ### rake[]
108
+ # Invokes a rake command.
109
+ #
110
+ # $ mina rake db:cleanup
111
+
67
112
  desc "Execute a Rake command in the current deploy."
68
113
  make_run_task[:rake, 'db:migrate']
69
114
 
115
+ # ### console
116
+ # Opens the Ruby console for the currently-deployed version.
117
+ #
118
+ # $ mina console
119
+
70
120
  desc "Starts an interactive console."
71
121
  task :console do
72
- queue echo_cmd %[cd "#{deploy_to!}/#{current_path!}" && #{rails} console]
122
+ queue echo_cmd %[cd "#{deploy_to!}/#{current_path!}" && #{rails} console && exit]
73
123
  end
74
124
 
125
+ # ## Deploy tasks
126
+ # These tasks are meant to be invoked inside deploy scripts, not invoked on
127
+ # their own.
128
+
75
129
  namespace :rails do
130
+ # ### rails:db_migrate
76
131
  desc "Migrates the Rails database (skips if nothing has changed since the last release)."
77
132
  task :db_migrate do
78
133
  if ENV['force_migrate']
@@ -99,6 +154,7 @@ namespace :rails do
99
154
  end
100
155
  end
101
156
 
157
+ # ### rails:db_migrate:force
102
158
  desc "Migrates the Rails database."
103
159
  task :'db_migrate:force' do
104
160
  queue %{
@@ -107,6 +163,7 @@ namespace :rails do
107
163
  }
108
164
  end
109
165
 
166
+ # ### rails:assets_precompile:force
110
167
  desc "Precompiles assets."
111
168
  task :'assets_precompile:force' do
112
169
  queue %{
@@ -115,6 +172,7 @@ namespace :rails do
115
172
  }
116
173
  end
117
174
 
175
+ # ### rails:assets_precompile
118
176
  desc "Precompiles assets (skips if nothing has changed since the last release)."
119
177
  task :'assets_precompile' do
120
178
  if ENV['force_assets']
@@ -0,0 +1,46 @@
1
+ # # Modules: rbenv
2
+ # Adds settings and tasks for managing [rbenv] installations.
3
+ #
4
+ # [rbenv]: https://github.com/sstephenson/rbenv
5
+ #
6
+ # require 'mina/rbenv'
7
+ #
8
+ # ## Common usage
9
+ #
10
+ # task :environment do
11
+ # invoke :'rbenv:load'
12
+ # end
13
+ #
14
+ # task :deploy => :environment do
15
+ # ...
16
+ # end
17
+
18
+ # ## Settings
19
+ # Any and all of these settings can be overriden in your `deploy.rb`.
20
+
21
+ # ### rbenv_path
22
+ # Sets the path where *rbenv* is installed.
23
+ #
24
+ # You may override this if rbenv is placed elsewhere in your setup.
25
+
26
+ set_default :rbenv_path, "$HOME/.rbenv"
27
+
28
+ # ## Tasks
29
+
30
+ # ### rbenv:load
31
+ # Loads the *rbenv* runtime.
32
+
33
+ task :'rbenv:load' do
34
+ queue %{
35
+ echo "-----> Loading rbenv"
36
+ #{echo_cmd %{export PATH="#{rbenv_path}/bin:$PATH"}}
37
+
38
+ if ! which -s rbenv >/dev/null; then
39
+ echo "! rbenv not found"
40
+ echo "! If rbenv is installed, check your :rbenv_path setting."
41
+ exit 1
42
+ fi
43
+
44
+ #{echo_cmd %{eval "$(rbenv init -)"}}
45
+ }
46
+ end
@@ -0,0 +1,58 @@
1
+ # # Modules: RVM
2
+ # Adds settings and tasks for managing [RVM] installations.
3
+ #
4
+ # [rvm]: http://rvm.io
5
+ #
6
+ # require 'mina/rvm'
7
+ #
8
+ # ## Common usage
9
+ #
10
+ # task :environment do
11
+ # invoke :'rvm:use[ruby-1.9.3-p125@gemset_name]'
12
+ # end
13
+ #
14
+ # task :deploy => :environment do
15
+ # ...
16
+ # end
17
+
18
+ # ## Settings
19
+ # Any and all of these settings can be overriden in your `deploy.rb`.
20
+
21
+ # ### rvm_path
22
+ # Sets the path to RVM.
23
+ #
24
+ # You can override this in your projects if RVM is installed in a different
25
+ # path, say, if you have a system-wide RVM install.
26
+
27
+ set_default :rvm_path, "$HOME/.rvm/scripts/rvm"
28
+
29
+ # ## Tasks
30
+
31
+ # ### rvm:use[]
32
+ # Uses a given RVM environment provided as an argument.
33
+ #
34
+ # This is usually placed in the `:environment` task.
35
+ #
36
+ # task :environment do
37
+ # invoke :'rvm:use[ruby-1.9.3-p125@gemset_name]'
38
+ # end
39
+ #
40
+ task :'rvm:use', :env do |t, args|
41
+ unless args[:env]
42
+ print_error "Task 'rvm:use' needs an RVM environment name as an argument."
43
+ print_error "Example: invoke :'rvm:use[ruby-1.9.2@default]'"
44
+ die
45
+ end
46
+
47
+ queue %{
48
+ echo "-----> Using RVM environment '#{args[:env]}'"
49
+ if [[ ! -s "#{rvm_path}" ]]; then
50
+ echo "! Ruby Version Manager not found"
51
+ echo "! If RVM is installed, check your :rvm_path setting."
52
+ exit 1
53
+ fi
54
+
55
+ source #{rvm_path}
56
+ #{echo_cmd %{rvm use "#{args[:env]}"}} || exit 1
57
+ }
58
+ end
@@ -1,5 +1,5 @@
1
1
  module Mina
2
2
  def self.version
3
- "0.2.0.pre2"
3
+ "0.2.0"
4
4
  end
5
5
  end
@@ -0,0 +1,28 @@
1
+ # # Modules: Whenever
2
+ # Adds settings and tasks for managing projects with [whenever}.
3
+ #
4
+ # [whenever]: http://rubygems.org/gems/whenever
5
+
6
+ namespace :whenever do
7
+ desc "Clear crontab"
8
+ task :clear do
9
+ queue %{
10
+ echo "-----> Clear crontab for #{domain}"
11
+ #{echo_cmd %[cd #{deploy_to!}/#{current_path!} ; bundle exec whenever --clear-crontab #{domain} --set 'environment=production&path=#{deploy_to!}/#{current_path!}']}
12
+ }
13
+ end
14
+ desc "Update crontab"
15
+ task :update do
16
+ queue %{
17
+ echo "-----> Update crontab for #{domain}"
18
+ #{echo_cmd %[cd #{deploy_to!}/#{current_path!} ; bundle exec whenever --update-crontab #{domain} --set 'environment=production&path=#{deploy_to!}/#{current_path!}']}
19
+ }
20
+ end
21
+ desc "Write crontab"
22
+ task :write do
23
+ queue %{
24
+ echo "-----> Update crontab for #{domain}"
25
+ #{echo_cmd %[cd #{deploy_to!}/#{current_path!} ; bundle exec whenever --write-crontab #{domain} --set 'environment=production&path=#{deploy_to!}/#{current_path!}']}
26
+ }
27
+ end
28
+ end
@@ -0,0 +1,15 @@
1
+ # Welcome to Mina
2
+
3
+ Really fast deployer and server automation tool.
4
+
5
+ Mina works really fast because it's a deploy Bash script generator. It
6
+ generates an entire procedure as a Bash script and runs it remotely in the
7
+ server.
8
+
9
+ Compare this to the likes of Vlad or Capistrano, where each command
10
+ is ran separately on their own SSH sessions. Mina only creates *one* SSH
11
+ session per deploy, minimizing the SSH connection overhead.
12
+
13
+ $ gem install mina
14
+ $ mina
15
+
@@ -0,0 +1,2 @@
1
+ Modules
2
+ =======
@@ -9,12 +9,12 @@ describe "Invoking the 'mina' command in a project" do
9
9
  it 'should echo commands in verbose mode' do
10
10
  mina 'deploy', '--verbose', '--simulate'
11
11
 
12
- stdout.should include %[echo "$ git]
12
+ stdout.should include %[echo #{Shellwords.escape('$ git')}]
13
13
  end
14
14
 
15
15
  it 'should not echo commands when not in verbose mode' do
16
16
  mina 'deploy', '--simulate'
17
17
 
18
- stdout.should_not include %[echo "$ git]
18
+ stdout.should_not include %[echo #{Shellwords.escape('$ git')}]
19
19
  end
20
20
  end
@@ -11,6 +11,8 @@
11
11
  # In fact, let's make that folder right now.
12
12
  require 'fileutils'
13
13
  FileUtils.mkdir_p "#{Dir.pwd}/deploy"
14
+ FileUtils.mkdir_p "#{Dir.pwd}/deploy/config"
15
+ File.open("#{Dir.pwd}/deploy/config/database.yml", 'w') { |f| f.write "Hello" }
14
16
 
15
17
  # -- Stubs end, deploy script begins! --------------
16
18
 
@@ -21,6 +23,11 @@ require 'mina/git'
21
23
  set :domain, 'localhost'
22
24
  set :deploy_to, "#{Dir.pwd}/deploy"
23
25
  set :repository, "#{Mina.root_path}"
26
+ set :shared_paths, ['config/database.yml']
27
+
28
+ task :environment do
29
+ queue %[echo "-----> Loading env"]
30
+ end
24
31
 
25
32
  desc "Deploys."
26
33
  task :deploy do
@@ -29,6 +36,7 @@ task :deploy do
29
36
  deploy do
30
37
  queue %[ruby -e "\\$stderr.write \\\"This is stdout output\n\\\""]
31
38
  invoke :'git:clone'
39
+ invoke :'deploy:link_shared_paths'
32
40
  invoke :'bundle:install'
33
41
  invoke :'rails:db_migrate'
34
42
 
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mina
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.pre2
5
- prerelease: 6
4
+ version: 0.2.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Rico Sta. Cruz
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-08-02 00:00:00.000000000 Z
13
+ date: 2012-09-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -90,9 +90,14 @@ files:
90
90
  - lib/mina/output_helpers.rb
91
91
  - lib/mina/rails.rb
92
92
  - lib/mina/rake.rb
93
+ - lib/mina/rbenv.rb
94
+ - lib/mina/rvm.rb
93
95
  - lib/mina/settings.rb
94
96
  - lib/mina/tools.rb
95
97
  - lib/mina/version.rb
98
+ - lib/mina/whenever.rb
99
+ - manual/index.md
100
+ - manual/modules.md
96
101
  - mina.gemspec
97
102
  - spec/command_helper.rb
98
103
  - spec/commands/command_spec.rb
@@ -124,9 +129,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
124
129
  required_rubygems_version: !ruby/object:Gem::Requirement
125
130
  none: false
126
131
  requirements:
127
- - - ! '>'
132
+ - - ! '>='
128
133
  - !ruby/object:Gem::Version
129
- version: 1.3.1
134
+ version: '0'
130
135
  requirements: []
131
136
  rubyforge_project:
132
137
  rubygems_version: 1.8.23