mina-traackr 0.3.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.
Files changed (62) hide show
  1. data/.gitignore +10 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +12 -0
  4. data/CONTRIBUTING.md +124 -0
  5. data/Gemfile +10 -0
  6. data/HISTORY.md +304 -0
  7. data/LICENSE +23 -0
  8. data/Makefile +29 -0
  9. data/Notes.md +72 -0
  10. data/Rakefile +20 -0
  11. data/Readme.md +1009 -0
  12. data/bin/mina +65 -0
  13. data/data/deploy.rb +74 -0
  14. data/data/deploy.sh.erb +120 -0
  15. data/lib/mina.rb +23 -0
  16. data/lib/mina/bundler.rb +44 -0
  17. data/lib/mina/chruby.rb +49 -0
  18. data/lib/mina/default.rb +144 -0
  19. data/lib/mina/deploy.rb +138 -0
  20. data/lib/mina/deploy_helpers.rb +34 -0
  21. data/lib/mina/exec_helpers.rb +104 -0
  22. data/lib/mina/foreman.rb +78 -0
  23. data/lib/mina/git.rb +62 -0
  24. data/lib/mina/helpers.rb +383 -0
  25. data/lib/mina/output_helpers.rb +92 -0
  26. data/lib/mina/rails.rb +206 -0
  27. data/lib/mina/rake.rb +9 -0
  28. data/lib/mina/rbenv.rb +47 -0
  29. data/lib/mina/rvm.rb +88 -0
  30. data/lib/mina/settings.rb +32 -0
  31. data/lib/mina/ssh_helpers.rb +122 -0
  32. data/lib/mina/tools.rb +20 -0
  33. data/lib/mina/version.rb +5 -0
  34. data/lib/mina/whenever.rb +27 -0
  35. data/manual/index.md +15 -0
  36. data/manual/modules.md +2 -0
  37. data/mina.gemspec +17 -0
  38. data/spec/command_helper.rb +52 -0
  39. data/spec/commands/cleanup_spec.rb +16 -0
  40. data/spec/commands/command_spec.rb +71 -0
  41. data/spec/commands/custom_config_spec.rb +20 -0
  42. data/spec/commands/deploy_spec.rb +40 -0
  43. data/spec/commands/outside_project_spec.rb +35 -0
  44. data/spec/commands/real_deploy_spec.rb +54 -0
  45. data/spec/commands/ssh_spec.rb +14 -0
  46. data/spec/commands/verbose_spec.rb +21 -0
  47. data/spec/dsl/invoke_spec.rb +33 -0
  48. data/spec/dsl/queue_spec.rb +49 -0
  49. data/spec/dsl/settings_in_rake_spec.rb +39 -0
  50. data/spec/dsl/settings_spec.rb +55 -0
  51. data/spec/dsl/to_spec.rb +20 -0
  52. data/spec/fixtures/custom_file_env/custom_deploy.rb +15 -0
  53. data/spec/fixtures/empty_env/config/deploy.rb +15 -0
  54. data/spec/helpers/output_helper_spec.rb +38 -0
  55. data/spec/spec_helper.rb +21 -0
  56. data/support/Readme-footer.md +32 -0
  57. data/support/Readme-header.md +17 -0
  58. data/support/guide.md +297 -0
  59. data/support/index.html +53 -0
  60. data/support/to_md.rb +11 -0
  61. data/test_env/config/deploy.rb +72 -0
  62. metadata +157 -0
@@ -0,0 +1,122 @@
1
+ # # Helpers: SSH helpers
2
+ # You don't need to invoke these helpers, they're already invoked automatically.
3
+
4
+ module Mina
5
+ module SshHelpers
6
+
7
+ # ### ssh
8
+ # Executes a command via SSH.
9
+ #
10
+ # Returns nothing usually, but if `{ return: true }` is given, returns the
11
+ # STDOUT output of the SSH session.
12
+ #
13
+ # `options` is a hash of options:
14
+ #
15
+ # - `:pretty` - Prettify the output if true.
16
+ # - `:return` - If set to true, returns the output.
17
+ #
18
+ # Example
19
+ #
20
+ # ssh("ls", return: true)
21
+
22
+ def ssh(cmd, options={})
23
+ require 'shellwords'
24
+
25
+ cmd = cmd.join("\n") if cmd.is_a?(Array)
26
+ script = Shellwords.escape(cmd)
27
+
28
+ if options[:return] == true
29
+ `#{ssh_command} -- #{script}`
30
+
31
+ elsif simulate_mode?
32
+ Ssh.simulate(cmd, ssh_command)
33
+
34
+ else
35
+ result = Ssh.invoke(script, self)
36
+ Ssh.ensure_successful result, self
37
+ end
38
+ end
39
+
40
+ # ### ssh_command
41
+ # Returns the SSH command to be executed.
42
+ #
43
+ # set :domain, 'foo.com'
44
+ # set :user, 'diggity'
45
+ #
46
+ # puts ssh_command
47
+ # #=> 'ssh diggity@foo.com'
48
+
49
+ def ssh_command
50
+ args = domain!.dup
51
+ args = "#{user}@#{args}" if user?
52
+ args << " -i #{identity_file}" if identity_file?
53
+ args << " -p #{port}" if port?
54
+ args << " -A" if forward_agent?
55
+ args << " #{ssh_options}" if ssh_options?
56
+ args << " -t"
57
+ "ssh #{args}"
58
+ end
59
+
60
+ # ## Private methods
61
+ # `ssh` delegates to these.
62
+
63
+ module Ssh
64
+
65
+ extend self
66
+
67
+ # ### Ssh.simulate
68
+ # __Internal:__ Prints SSH command. Called by `ssh`.
69
+
70
+ def simulate(cmd, ssh_command)
71
+ str = "Executing the following via '#{ssh_command}':"
72
+ puts "#!/usr/bin/env bash"
73
+ puts "# #{str}"
74
+ puts "#"
75
+
76
+ puts cmd
77
+
78
+ 0
79
+ end
80
+
81
+ # ### Ssh.invoke
82
+ # __Internal:__ Initiates an SSH session with script `script` with given
83
+ # `term_mode`. Called by `ssh`.
84
+
85
+ def invoke(script, this)
86
+ term_mode = :"#{this.settings.term_mode}"
87
+ code = "#{this.ssh_command} -- #{script}"
88
+
89
+ # Certain environments can't do :pretty mode.
90
+ term_mode = :exec if term_mode == :pretty && !pretty_supported?
91
+
92
+ case term_mode
93
+ when :pretty
94
+ this.pretty_system(code)
95
+ when :exec
96
+ exec code
97
+ else
98
+ system code
99
+ $?.to_i
100
+ end
101
+ end
102
+
103
+ def pretty_supported?
104
+ # open4 is not supported under Windows.
105
+ # https://github.com/nadarei/mina/issues/58
106
+ require 'rbconfig'
107
+ ! (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/)
108
+ end
109
+
110
+ # ### Ssh.ensure_successful
111
+ # __Internal:__ Halts the execution if the given result code is not
112
+ # successful (non-zero).
113
+
114
+ def ensure_successful(result, this)
115
+ this.die result if result.is_a?(Fixnum) && result > 0
116
+ result
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+ end
@@ -0,0 +1,20 @@
1
+ module Mina
2
+ module Tools
3
+ if IO.respond_to?(:popen4)
4
+ def self.popen4(*cmd, &blk)
5
+ IO.popen4 *cmd, &blk
6
+ $?
7
+ end
8
+ else
9
+ def self.popen4(*cmd, &blk)
10
+ require 'open4'
11
+ Open4.popen4 *cmd, &blk
12
+ end
13
+ end
14
+
15
+ def self.pfork4(*cmd, &blk)
16
+ require 'open4'
17
+ Open4.pfork4 *cmd, &blk
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ module Mina
2
+ def self.version
3
+ "0.3.0"
4
+ end
5
+ end
@@ -0,0 +1,27 @@
1
+ # # Modules: Whenever
2
+ # Adds settings and tasks for managing projects with [whenever].
3
+ # [whenever]: http://rubygems.org/gems/whenever
4
+
5
+ namespace :whenever do
6
+ desc "Clear crontab"
7
+ task :clear do
8
+ queue %{
9
+ echo "-----> Clear crontab for #{domain}_#{rails_env}"
10
+ #{echo_cmd %[cd #{deploy_to!}/#{current_path!} ; bundle exec whenever --clear-crontab #{domain}_#{rails_env} --set 'environment=#{rails_env}&path=#{deploy_to!}/#{current_path!}']}
11
+ }
12
+ end
13
+ desc "Update crontab"
14
+ task :update do
15
+ queue %{
16
+ echo "-----> Update crontab for #{domain}_#{rails_env}"
17
+ #{echo_cmd %[cd #{deploy_to!}/#{current_path!} ; bundle exec whenever --update-crontab #{domain}_#{rails_env} --set 'environment=#{rails_env}&path=#{deploy_to!}/#{current_path!}']}
18
+ }
19
+ end
20
+ desc "Write crontab"
21
+ task :write do
22
+ queue %{
23
+ echo "-----> Update crontab for #{domain}_#{rails_env}"
24
+ #{echo_cmd %[cd #{deploy_to!}/#{current_path!} ; bundle exec whenever --write-crontab #{domain}_#{rails_env} --set 'environment=#{rails_env}&path=#{deploy_to!}/#{current_path!}']}
25
+ }
26
+ end
27
+ 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
+ =======
@@ -0,0 +1,17 @@
1
+ require './lib/mina/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "mina-traackr"
5
+ s.version = Mina.version
6
+ s.summary = %{Really fast deployer and server automation tool.}
7
+ s.description = %Q{Really fast deployer and server automation tool.}
8
+ s.authors = ["Rico Sta. Cruz", "Michael Galero"]
9
+ s.email = ["rico@nadarei.co", "mikong@nadarei.co"]
10
+ s.homepage = "http://github.com/nadarei/mina"
11
+ s.files = `git ls-files`.strip.split("\n")
12
+ s.executables = Dir["bin/*"].map { |f| File.basename(f) }
13
+
14
+ s.add_dependency "rake"
15
+ s.add_dependency "open4"
16
+ s.add_development_dependency "rspec"
17
+ end
@@ -0,0 +1,52 @@
1
+ # Invokes the main 'mina' command.
2
+ def run_command(*args)
3
+ out = ''
4
+ err = ''
5
+ @result = nil
6
+
7
+ if ENV['rake']
8
+ rake_version = "~> #{ENV['rake'] || '0.9'}.0"
9
+ script = %[require 'rubygems' unless Object.const_defined?(:Gem);]
10
+ script += %[gem 'rake', '#{rake_version}';]
11
+ script += %[load '#{root('bin/mina')}']
12
+ cmd = ['ruby', '-e', "#{script}", "--", *args]
13
+ else
14
+ cmd = [root('bin/mina'), *args]
15
+ end
16
+
17
+ status =
18
+ Mina::Tools.popen4(*cmd) do |pid, i, o, e|
19
+ out = o.read
20
+ err = e.read
21
+ end
22
+
23
+ @result = status.exitstatus
24
+
25
+ @out = out
26
+ @err = err
27
+
28
+ @result
29
+ end
30
+
31
+ # Invokes the main 'mina' command and ensures the exit status is success.
32
+ def mina(*args)
33
+ run_command *args
34
+ if exitstatus != 0 && ENV['verbose']
35
+ puts stdout
36
+ puts stderr
37
+ end
38
+
39
+ exitstatus.should == 0
40
+ end
41
+
42
+ def stdout
43
+ @out
44
+ end
45
+
46
+ def stderr
47
+ @err
48
+ end
49
+
50
+ def exitstatus
51
+ @result
52
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+ require 'command_helper'
3
+
4
+ describe "Invoking the 'mina deploy:cleanup' command" do
5
+ before :each do
6
+ Dir.chdir root('test_env')
7
+ end
8
+
9
+ it "should cleanup old deployments" do
10
+ 3.times { mina 'deploy' }
11
+
12
+ mina 'deploy:cleanup'
13
+
14
+ Dir["deploy/releases/*"].length.should == 2
15
+ end
16
+ end
@@ -0,0 +1,71 @@
1
+ require 'spec_helper'
2
+ require 'command_helper'
3
+
4
+ describe "Invoking the 'mina' command in a project" do
5
+ before :each do
6
+ Dir.chdir root('test_env')
7
+ end
8
+
9
+ it "should think it's 'mina', not 'rake' (1)" do
10
+ run_command 'pinkledills'
11
+ exitstatus.should_not == 0
12
+ stderr.should include 'mina aborted'
13
+ end
14
+
15
+ it "should think it's 'mina', not 'rake' (1)" do
16
+ mina '-T'
17
+ stdout.should include 'mina help'
18
+ stdout.should include 'mina git:clone'
19
+ end
20
+
21
+ it 'with --version should print the version' do
22
+ mina '--version'
23
+ stdout.should include Mina.version
24
+ end
25
+
26
+ it 'with -V should print the version' do
27
+ mina '-V'
28
+ stdout.should include Mina.version
29
+ end
30
+
31
+ describe 'without arguments' do
32
+ before :each do
33
+ mina
34
+ end
35
+
36
+ it 'should print standard help tasks' do
37
+ mina
38
+ stdout.should include 'mina help'
39
+ stdout.should include 'mina init'
40
+ stdout.should include 'mina tasks'
41
+ end
42
+
43
+ it 'should print project-specific tasks' do
44
+ mina
45
+ stdout.should include 'mina deploy'
46
+ stdout.should include 'mina restart'
47
+ stdout.should include 'mina setup'
48
+ end
49
+
50
+ it "should be the same as running 'help'" do
51
+ previous_out = stdout
52
+
53
+ mina 'help'
54
+ stdout.should == previous_out
55
+ end
56
+ end
57
+
58
+ it "with 'mina -f' on a non-existing file should fail" do
59
+ run_command '-f', 'foobar'
60
+ stderr.should include 'mina aborted'
61
+ stderr.should include 'No Rakefile found'
62
+ end
63
+
64
+ it "with 'mina tasks' should print tasks" do
65
+ mina 'tasks'
66
+
67
+ stdout.should include('bundle:install')
68
+ stdout.should include('Install gem dependencies using Bundler')
69
+ stdout.should include('passenger:restart')
70
+ end
71
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+ require 'command_helper'
3
+
4
+ describe "Invoking the 'mina' command in a project without a deploy.rb" do
5
+ before :each do
6
+ Dir.chdir root('spec/fixtures/custom_file_env')
7
+ FileUtils.rm_rf 'deploy'
8
+ end
9
+
10
+ it 'should fail' do
11
+ run_command 'deploy', '--simulate'
12
+ exitstatus.should be > 0
13
+ end
14
+
15
+ it 'should pass if you provide a new rakefile' do
16
+ mina 'deploy', '--simulate', '-f', 'custom_deploy.rb'
17
+ stdout.should include 'Creating a temporary build path'
18
+ end
19
+ end
20
+
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'command_helper'
3
+
4
+ describe "Invoking the 'mina' command in a project" do
5
+ before :each do
6
+ Dir.chdir root('test_env')
7
+ end
8
+
9
+ describe "to do a simulated deploy" do
10
+ before :each do
11
+ mina 'deploy', 'simulate=1'
12
+ end
13
+
14
+ it "should take care of the lockfile" do
15
+ stdout.should =~ /ERROR: another deployment is ongoing/
16
+ stdout.should =~ /touch ".*deploy\.lock"/
17
+ stdout.should =~ /rm -f ".*deploy\.lock"/
18
+ end
19
+
20
+ it "should honor releases_path" do
21
+ stdout.should include "releases/"
22
+ end
23
+
24
+ it "should symlink the current_path" do
25
+ stdout.should =~ /ln .*current/
26
+ end
27
+
28
+ it "should include deploy directives" do
29
+ stdout.should include "bundle exec rake db:migrate"
30
+ end
31
+
32
+ it "should include 'to :build' directives" do
33
+ stdout.should include "touch build.txt"
34
+ end
35
+
36
+ it "should include 'to :launch' directives" do
37
+ stdout.should include "touch tmp/restart.txt"
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'command_helper'
3
+
4
+ describe "Invoking the 'mina' command outside a project" do
5
+ before :each do
6
+ Dir.chdir root
7
+ end
8
+
9
+ describe "without arguments" do
10
+ before :each do
11
+ mina
12
+ end
13
+
14
+ it 'should print standard help tasks' do
15
+ stdout.should include('mina help')
16
+ stdout.should include('mina init')
17
+ stdout.should include('mina tasks')
18
+ end
19
+
20
+ it "should not print project-specific tasks" do
21
+ stdout.should_not include('mina deploy')
22
+ stdout.should_not include('mina restart')
23
+ stdout.should_not include('mina setup')
24
+ end
25
+
26
+ %w[-h --help].each do |arg|
27
+ it "should have the same output as 'mina #{arg}'" do
28
+ @previous_output = stdout
29
+ mina arg
30
+ stdout.should == @previous_output
31
+ end
32
+ end
33
+ end
34
+ end
35
+