mina 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 48b10c2f04fe8cd4a81515ad180b07e988e30315
4
+ data.tar.gz: a6eb8c996ad4128d29096ce7f7307f007e0bc207
5
+ SHA512:
6
+ metadata.gz: 58ff29681d74382796c04253d9d29d7af8eb4c10b13788d6e66004975cd1c520a1b764de1f21b9cfd62e57e59a521f30e3c948c6b8eccfb8a8397e9560d1bb70
7
+ data.tar.gz: e446b721204e02b30683df7f6bc785098bd809d83b7a0bf48b9c725d77666acaebd03138b877447096e9b355b0726effb661fe61cda7974e7342eb397591ece9
data/.gitignore CHANGED
@@ -1,6 +1,8 @@
1
1
  doc
2
2
  test_env/deploy
3
3
  .rvmrc
4
+ .ruby-gemset
5
+ .ruby-version
4
6
  Gemfile.lock
5
7
  pkg/
6
8
  docs
data/.travis.yml CHANGED
@@ -2,11 +2,11 @@ language: ruby
2
2
  rvm:
3
3
  - 1.8.7
4
4
  - 1.9.3
5
- - rbx-18mode
6
- - rbx-19mode
7
5
  env:
8
6
  - "rake=0.8"
9
7
  - "rake=0.9"
8
+ - "rake=10"
10
9
  script: "bundle exec rspec"
11
10
  notifications:
12
- email: false
11
+ email:
12
+ - dropbox+travis@ricostacruz.com
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,124 @@
1
+ # Contributing to Mina
2
+
3
+ Want to get involved? Thanks! There are plenty of ways to help!
4
+
5
+ ## Reporting issues
6
+
7
+ A bug is a _demonstrable problem_ that is caused by the code in the
8
+ repository.
9
+
10
+ Please read the following guidelines before you [report an issue][issues]:
11
+
12
+ 1. **Use the GitHub issue search** — check if the issue has already been
13
+ reported. If it has been, please comment on the existing issue.
14
+
15
+ 2. **Check if the issue has been fixed** — the latest `master` or
16
+ development branch may already contain a fix.
17
+
18
+ 3. **Isolate the demonstrable problem** — make sure that the code in the
19
+ project's repository is _definitely_ responsible for the issue. Create a
20
+ [reduced test case](http://css-tricks.com/6263-reduced-test-cases/) - an
21
+ extremely simple and immediately viewable example of the issue.
22
+
23
+ Please try to be as detailed as possible in your report too. What is your
24
+ environment? What steps will reproduce the issue? What would you expect to be
25
+ the outcome? All these details will help people to assess and fix any potential
26
+ bugs.
27
+
28
+ ### Example of a good bug report:
29
+
30
+ > Short and descriptive title
31
+ >
32
+ > A summary of the issue and the OS environment in which it occurs. If
33
+ > suitable, include the steps required to reproduce the bug.
34
+ >
35
+ > 1. This is the first step
36
+ > 2. This is the second step
37
+ > 3. Further steps, etc.
38
+ >
39
+ > `<url>` (a link to the reduced test case)
40
+ >
41
+ > Any other information you want to share that is relevant to the issue being
42
+ > reported. This might include the lines of code that you have identified as
43
+ > causing the bug, and potential solutions (and your opinions on their
44
+ > merits).
45
+
46
+ A good bug report shouldn't leave people needing to chase you up to get further
47
+ information that is required to assess or fix the bug.
48
+
49
+ **[File a bug report][issues]**
50
+
51
+ ## Responding to issues
52
+
53
+ Feel free to respond to other people's issues! Some people may be reporting
54
+ issues that can easily be solved even without modification to the project's
55
+ code.
56
+
57
+ You can also help by verifying issues reported.
58
+
59
+ **[View issues][issues]**
60
+
61
+ ## The 'help wanted' tag
62
+
63
+ Some [issues] are tagged with the 'help wanted' tag. These issues often:
64
+
65
+ - are missing an actual implementation, or
66
+ - need people's help in verifying and replicating the issue, or
67
+ - need test cases.
68
+
69
+ If you would like to contribute code and don't have any specific issue you want
70
+ to fix, this would be a good place to start looking at!
71
+
72
+ **[View issues][issues]**
73
+
74
+ ## Pull requests
75
+
76
+ Good pull requests — patches, improvements, new features — are a fantastic
77
+ help. They should remain focused in scope and avoid containing unrelated
78
+ commits.
79
+
80
+ If your contribution involves a significant amount of work or substantial
81
+ changes to any part of the project, please open an issue to discuss it first.
82
+
83
+ Please follow this process; it's the best way to get your work included in the
84
+ project:
85
+
86
+ 1. [Fork](http://help.github.com/fork-a-repo/) the project.
87
+
88
+ 2. Clone your fork (`git clone
89
+ https://github.com/<your-username>/html5-boilerplate.git`).
90
+
91
+ 3. Add an `upstream` remote (`git remote add upstream
92
+ https://github.com/nadarei/mina.git`).
93
+
94
+ 4. Get the latest changes from upstream (e.g. `git pull upstream
95
+ <dev-branch>`).
96
+
97
+ 5. Create a new topic branch to contain your feature, change, or fix (`git
98
+ checkout -b <topic-branch-name>`).
99
+
100
+ 6. Make sure that your changes adhere to the current coding conventions used
101
+ throughout the project - indentation, accurate comments, etc. Please update
102
+ any documentation that is relevant to the change you are making.
103
+
104
+ 7. Commit your changes in logical chunks; use git's [interactive
105
+ rebase](https://help.github.com/articles/interactive-rebase) feature to tidy
106
+ up your commits before making them public. Please adhere to these [git commit
107
+ message
108
+ guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
109
+ or your pull request is unlikely be merged into the main project.
110
+
111
+ 8. Locally merge (or rebase) the upstream branch into your topic branch.
112
+
113
+ 9. Push your topic branch up to your fork (`git push origin
114
+ <topic-branch-name>`).
115
+
116
+ 10. [Open a Pull Request](http://help.github.com/send-pull-requests/) with a
117
+ clear title and description. Please mention which browsers you tested in.
118
+
119
+ ## Acknowledgements
120
+
121
+ This contributing guide has been adapted from [HTML5 boilerplate's guide][g].
122
+
123
+ [g]: https://github.com/h5bp/html5-boilerplate/blob/master/CONTRIBUTING.md
124
+ [issues]: https://github.com/nadarei/mina/issues/
data/Gemfile CHANGED
@@ -4,7 +4,7 @@
4
4
  # development dependencies of our dependencies, and those are not conflict free.
5
5
  # So, here we are, `bundle install`.
6
6
 
7
- source :rubygems
7
+ source "https://rubygems.org"
8
8
  gemspec
9
9
 
10
10
  gem 'rake', "~> #{ENV['rake'] || "0.9"}.0"
data/HISTORY.md CHANGED
@@ -1,3 +1,36 @@
1
+ v0.3.0 - July 10, 2013
2
+ ----------------------
3
+
4
+ * **Stdin is now being passed, thereby making git prompts work.**
5
+ * Foreman: Add foreman support. (#71) [Dan Sosedoff]
6
+ * Foreman: Fix 'command not found' error. (#89, #101)
7
+ * Foreman: Fix forman stop. [Andrew Rosa]
8
+ * Fix `mina setup` showing an error. (#64) [Anthony Hristov]
9
+ * Fix "broken pipe" error after deploying. (#64) [Tomas Varneckas]
10
+ * Fix error regarding "open4" in Windows environments. (#58)
11
+ * Fix the default script's "touch tmp/restart.txt" to work for reliably. (#77)
12
+ [Eugene Diachkin]
13
+ * Fix errors that happen when the host string is frozen. [sonots]
14
+ * RVM: use 'rvm use --create'. (#81) [Marcos Beirigo]
15
+ * RVM: Add 'rvm:wrapper' task to create wrappers. (#81) [Marcos Beirigo]
16
+ * New helper method called 'capture' to capture SSH output. (#113) [Naoki
17
+ Ainoya]
18
+ * Fix encoding errors. (#68) [Faud Saud]
19
+
20
+ Special thanks to all the contributors who made this release happen.
21
+
22
+ https://github.com/nadarei/mina/compare/v0.2.1...v0.3.0
23
+
24
+ [sonots]: https://github.com/sonots
25
+ [Tomas Varneckas]: https://github.com/tomasv
26
+ [Anthony Hristov]: https://github.com/muxcmux
27
+ [Dan Sosedoff]: https://github.com/sosedoff
28
+ [Eugene Diachkin]: https://github.com/ineu
29
+ [Marcos Beirigo]: https://github.com/marcosbeirigo
30
+ [Andrew Rosa]: https://github.com/andrewhr
31
+ [Naoki Ainoya]: https://github.com/saketoba
32
+ [Faud Saud]: https://github.com/faudsaud
33
+
1
34
  v0.2.1 - Sep 08, 2012
2
35
  ---------------------
3
36
 
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Mina [![status](https://secure.travis-ci.org/nadarei/mina.png?branch=master)](http://travis-ci.org/nadarei/mina)
1
+ # Mina
2
2
 
3
3
  Really fast deployer and server automation tool.
4
4
 
@@ -13,6 +13,8 @@ session per deploy, minimizing the SSH connection overhead.
13
13
  $ gem install mina
14
14
  $ mina
15
15
 
16
+ [![Status](https://secure.travis-ci.org/nadarei/mina.png?branch=master)](http://travis-ci.org/nadarei/mina) [![Version](https://badge.fury.io/rb/mina.png)](http://badge.fury.io/rb/mina)
17
+
16
18
  Documentation
17
19
  -------------
18
20
 
@@ -39,6 +41,7 @@ To test out stuff in development:
39
41
  # Run specs
40
42
  $ rspec
41
43
  $ rspec -t ssh # Run SSH tests (read test_env/config/deploy.rb first)
44
+ $ rake=10 rspec
42
45
  $ rake=0.9 rspec
43
46
  $ rake=0.8 rspec
44
47
 
@@ -108,3 +111,4 @@ Michael:
108
111
  [nd]: http://nadarei.co
109
112
  [issues]: https://github.com/nadarei/mina/issues
110
113
  [trello]: https://trello.com/board/mina/4fc8b3023d9c9a4d72e573e6
114
+
data/data/deploy.rb CHANGED
@@ -45,7 +45,7 @@ task :setup => :environment do
45
45
  queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/config"]
46
46
 
47
47
  queue! %[touch "#{deploy_to}/shared/config/database.yml"]
48
- queue %[-----> Be sure to edit 'shared/config/database.yml'.]
48
+ queue %[echo "-----> Be sure to edit 'shared/config/database.yml'."]
49
49
  end
50
50
 
51
51
  desc "Deploys the current version to the server."
@@ -60,7 +60,7 @@ task :deploy => :environment do
60
60
  invoke :'rails:assets_precompile'
61
61
 
62
62
  to :launch do
63
- queue 'touch tmp/restart.txt'
63
+ queue "touch #{deploy_to}/tmp/restart.txt"
64
64
  end
65
65
  end
66
66
  end
data/lib/mina.rb CHANGED
@@ -7,6 +7,7 @@ module Mina
7
7
  autoload :DeployHelpers, 'mina/deploy_helpers'
8
8
  autoload :OutputHelpers, 'mina/output_helpers'
9
9
  autoload :SshHelpers, 'mina/ssh_helpers'
10
+ autoload :ExecHelpers, 'mina/exec_helpers'
10
11
  autoload :Helpers, 'mina/helpers'
11
12
  autoload :Settings, 'mina/settings'
12
13
  autoload :Tools, 'mina/tools'
@@ -0,0 +1,104 @@
1
+ # # Helpers: Exec helpers
2
+ # Provides `pretty_system` which Mina uses to parse SSH output, and delegate to
3
+ # the appropriate Output helper.
4
+
5
+ module Mina
6
+ module ExecHelpers
7
+
8
+ # ### pretty_system
9
+ # __Internal:__ A pretty version of the default `#system` commands, but
10
+ # indents and puts color.
11
+ #
12
+ # Returns the exit code in integer form.
13
+ #
14
+ def pretty_system(code)
15
+ require 'shellwords'
16
+ cmds = Shellwords.shellsplit(code)
17
+ coathooks = 0
18
+
19
+ status =
20
+ Tools.popen4(*cmds) do |pid, i, o, e|
21
+ # Handle `^C`.
22
+ trap("INT") { Sys.handle_sigint(coathooks += 1, pid, self) }
23
+
24
+ # __In the background,__ make stdin passthru, and stream stderr.
25
+ pid_err = Sys.stream_stderr!(e) { |str| print_stderr str }
26
+ pid_in = Sys.stream_stdin! { |chr| i.putc chr }
27
+
28
+ # __In the foreground,__ stream stdout to the output helper.
29
+ Sys.stream_stdout(o) { |ch| print_char ch }
30
+
31
+ Process.waitpid pid_err
32
+ Process.kill 'TERM', pid_in
33
+ end
34
+
35
+ status.exitstatus
36
+ end
37
+
38
+ # ## Private methods
39
+ # Delegate functions, mostly.
40
+
41
+ module Sys
42
+
43
+ extend self
44
+
45
+ # ### Sys.handle_sigint!
46
+ # Called when a `^C` is pressed. The param `count` is how many times it's
47
+ # been pressed since. Returns nothing.
48
+
49
+ def handle_sigint(count, pid, this)
50
+ puts ""
51
+ if count > 1
52
+ this.print_status "Mina: SIGINT received again. Force quitting..."
53
+ Process.kill "KILL", pid
54
+ else
55
+ this.print_status "Mina: SIGINT received."
56
+ Process.kill "TERM", pid
57
+ end
58
+ end
59
+
60
+ # ### Sys.stream_stderr!
61
+ # __Internal:__ Read from stderr stream `err` *[0]*, supress expected
62
+ # errors *[1]*, and yield. Returns the PID.
63
+
64
+ def stream_stderr!(err, &blk)
65
+ fork do
66
+ trap("INT") {}
67
+
68
+ while str = err.gets #[0]
69
+ next if str.include? "bash: no job control in this shell" #[1]
70
+ next if str.include? "stdin is not a terminal"
71
+
72
+ yield str.strip #[2]
73
+ end
74
+ end
75
+ end
76
+
77
+ # ### Sys.stream_stdin!
78
+ # __Internal:__ Read from the real stdin stream and pass it onto the given
79
+ # stdin stream `i`. Returns the PID.
80
+
81
+ def stream_stdin!(&blk)
82
+ fork do
83
+ trap("INT") {}
84
+
85
+ while (char = STDIN.getbyte rescue nil)
86
+ yield char if char
87
+ end
88
+ end
89
+ end
90
+
91
+ # ### Sys.stream_stdout
92
+ # __Internal:__ Read from given stdout stream `o` and delegate it to the
93
+ # output helper.
94
+
95
+ def stream_stdout(o, &blk)
96
+ while str = o.getc
97
+ yield str
98
+ end
99
+ end
100
+
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,78 @@
1
+ # # Modules: Foreman
2
+ # Adds settings and tasks for managing projects with [foreman].
3
+ #
4
+ # NOTE: Requires sudo privileges
5
+ #
6
+ # [foreman]: http://rubygems.org/ddolar/foreman
7
+ #
8
+ # require 'mina/foreman'
9
+ #
10
+ # ## Common usage
11
+ #
12
+ # set :application, "app-name"
13
+ #
14
+ # task :deploy => :environment do
15
+ # deploy do
16
+ # # ...
17
+ # invoke 'foreman:export'
18
+ # # ...
19
+ # end
20
+ #
21
+ # to :launch do
22
+ # invoke 'foreman:restart'
23
+ # end
24
+ # end
25
+ #
26
+
27
+ # ## Settings
28
+ # Any and all of these settings can be overriden in your `deploy.rb`.
29
+
30
+ # ### foreman_app
31
+ # Sets the service name that foreman will export to upstart. Uses *application*
32
+ # variable as a default. It should be set, otherwise export command will fail.
33
+
34
+ # ### foreman_user
35
+ # Sets the user under which foreman will execute the service. Defaults to *user*
36
+
37
+ # ### foreman_log
38
+ # Sets the foreman log path. Defaults to *shared/log*
39
+
40
+ set_default :foreman_app, lambda { application }
41
+ set_default :foreman_user, lambda { user }
42
+ set_default :foreman_log, lambda { "#{deploy_to!}/#{shared_path}/log" }
43
+
44
+ namespace :foreman do
45
+ desc 'Export the Procfile to Ubuntu upstart scripts'
46
+ task :export do
47
+ export_cmd = "sudo bundle exec foreman export upstart /etc/init -a #{foreman_app} -u #{foreman_user} -l #{foreman_log}"
48
+
49
+ queue %{
50
+ echo "-----> Exporting foreman procfile for #{foreman_app}"
51
+ #{echo_cmd %[cd #{deploy_to!}/#{current_path!} ; #{export_cmd}]}
52
+ }
53
+ end
54
+
55
+ desc "Start the application services"
56
+ task :start do
57
+ queue %{
58
+ echo "-----> Starting #{foreman_app} services"
59
+ #{echo_cmd %[sudo start #{foreman_app}]}
60
+ }
61
+ end
62
+
63
+ desc "Stop the application services"
64
+ task :stop do
65
+ queue %{
66
+ echo "-----> Stopping #{foreman_app} services"
67
+ #{echo_cmd %[sudo stop #{foreman_app}]}
68
+ }
69
+ end
70
+
71
+ desc "Restart the application services"
72
+ task :restart do
73
+ queue %{
74
+ echo "-----> Restarting #{foreman_app} services"
75
+ #{echo_cmd %[sudo start #{foreman_app} || sudo restart #{foreman_app}]}
76
+ }
77
+ end
78
+ end
data/lib/mina/git.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  # # Modules: Git
2
4
  # Adds settings and tasks related to managing Git.
3
5
  #
data/lib/mina/helpers.rb CHANGED
@@ -10,9 +10,14 @@ module Mina
10
10
  #
11
11
  # invoke :'git:clone'
12
12
  # invoke :restart
13
+ #
14
+ # Options:
15
+ # reenable (bool) - Execute the task even next time.
16
+ #
13
17
 
14
- def invoke(task)
18
+ def invoke(task, options = {})
15
19
  Rake.application.invoke_task task
20
+ Rake::Task[task].reenable if options[:reenable]
16
21
  end
17
22
 
18
23
  # ### erb
@@ -151,6 +156,7 @@ module Mina
151
156
 
152
157
  def echo_cmd(str)
153
158
  if verbose_mode?
159
+ require 'shellwords'
154
160
  "echo #{Shellwords.escape("$ " + str)} &&\n#{str}"
155
161
  else
156
162
  str
@@ -361,5 +367,11 @@ module Mina
361
367
  indent n, unindent(code)
362
368
  end
363
369
 
370
+ # ### capture
371
+ # Returns the output of command via SSH.
372
+ def capture(cmd, options={})
373
+ ssh cmd, options.merge(:return => true)
374
+ end
375
+
364
376
  end
365
377
  end
@@ -19,18 +19,38 @@ module Mina
19
19
  #
20
20
  # Returns nothing.
21
21
  #
22
- def print_str(str)
23
- if str =~ /^\-+> (.*?)$/
22
+ def print_str(line)
23
+ if line =~ /^\-+> (.*?)$/
24
24
  print_status $1
25
- elsif str =~ /^! (.*?)$/
25
+ elsif line =~ /^! (.*?)$/
26
26
  print_error $1
27
- elsif str =~ /^\$ (.*?)$/
27
+ elsif line =~ /^\$ (.*?)$/
28
28
  print_command $1
29
29
  else
30
- print_stdout str
30
+ print_stdout line
31
31
  end
32
32
  end
33
33
 
34
+ # ### print_char
35
+ # Prints a single character.
36
+ def print_char(ch)
37
+ $last ||= ''
38
+
39
+ if ch == "\n"
40
+ print_clear
41
+ print_str $last
42
+ $last = ''
43
+ else
44
+ print ' ' if $last == ''
45
+ print ch
46
+ $last += ch
47
+ end
48
+ end
49
+
50
+ def print_clear
51
+ print "\033[1K\r"
52
+ end
53
+
34
54
  # ### print_status
35
55
  # Prints a status message. (`----->`)
36
56
  def print_status(msg)
@@ -68,59 +88,5 @@ module Mina
68
88
  def color(str, c)
69
89
  ENV['NO_COLOR'] ? str : "\033[#{c}m#{str}\033[0m"
70
90
  end
71
-
72
- # ### pretty_system
73
- # __Internal:__ Works like `system`, but indents and puts color.
74
- #
75
- # Returns the exit code in integer form.
76
- #
77
- def pretty_system(code)
78
- require 'shellwords'
79
- cmds = Shellwords.shellsplit(code)
80
- interrupted = false
81
-
82
- status =
83
- Tools.popen4(*cmds) do |pid, i, o, e|
84
- trap "INT" do
85
- puts ""
86
- unless interrupted
87
- print_status "Mina: SIGINT received."
88
- Process.kill "TERM", pid
89
- interrupted = true
90
- else
91
- print_status "Mina: SIGINT received again. Force quitting..."
92
- Process.kill "KILL", pid
93
- end
94
- end
95
-
96
- # Read stderr in the background.
97
- p1 = fork do
98
- trap("INT") {}
99
- while str = e.gets
100
- # Supress expected errors.
101
- next if str.include? "bash: no job control in this shell"
102
- next if str.include? "stdin is not a terminal"
103
- print_stderr str.strip
104
- end
105
- end
106
-
107
- # Read stdin in the background and send it out.
108
- p2 = fork do
109
- trap("INT") {}
110
- while (char = STDIN.getbyte rescue nil)
111
- i.putc char if char
112
- end
113
- end
114
-
115
- # Read stdout.
116
- while str = o.gets
117
- print_str str
118
- end
119
-
120
- Process.waitpid p1
121
- end
122
-
123
- status.exitstatus
124
- end
125
91
  end
126
92
  end
data/lib/mina/rake.rb CHANGED
@@ -3,6 +3,7 @@ extend Mina::Helpers
3
3
  extend Mina::DeployHelpers
4
4
  extend Mina::SshHelpers
5
5
  extend Mina::OutputHelpers
6
+ extend Mina::ExecHelpers
6
7
 
7
8
  require 'mina/default'
8
9
  require 'mina/deploy' if Rake.application.have_rakefile
data/lib/mina/rvm.rb CHANGED
@@ -53,6 +53,38 @@ task :'rvm:use', :env do |t, args|
53
53
  fi
54
54
 
55
55
  source #{rvm_path}
56
- #{echo_cmd %{rvm use "#{args[:env]}"}} || exit 1
56
+ #{echo_cmd %{rvm use "#{args[:env]}" --create}} || exit 1
57
57
  }
58
58
  end
59
+
60
+
61
+ # ### rvm:wrapper[]
62
+ # Creates a rvm wrapper for a given executable
63
+ #
64
+ # This is usually placed in the `:setup` task.
65
+ #
66
+ # task ::setup => :environment do
67
+ # ...
68
+ # invoke :'rvm:wrapper[ruby-1.9.3-p125@gemset_name,wrapper_name,binary_name]'
69
+ # end
70
+ #
71
+ task :'rvm:wrapper', :env, :name, :bin do |t,args|
72
+ unless args[:env] && args[:name] && args[:bin]
73
+ print_error "Task 'rvm:wrapper' needs an RVM environment name, an wrapper name and the binary name as arguments"
74
+ print_error "Example: invoke :'rvm:use[ruby-1.9.2@myapp,myapp,unicorn_rails]'"
75
+ die
76
+ end
77
+
78
+ queue %{
79
+ echo "-----> creating RVM wrapper '#{args[:name]}_#{args[:bin]}' using '#{args[:env]}'"
80
+ if [[ ! -s "#{rvm_path}" ]]; then
81
+ echo "! Ruby Version Manager not found"
82
+ echo "! If RVM is installed, check your :rvm_path setting."
83
+ exit 1
84
+ fi
85
+
86
+ source #{rvm_path}
87
+ #{echo_cmd %{rvm wrapper #{args[:env]} #{args[:name]} #{args[:bin]} }} || exit 1
88
+ }
89
+
90
+ end
@@ -1,8 +1,9 @@
1
1
  # # Helpers: SSH helpers
2
2
  # You don't need to invoke these helpers, they're already invoked automatically.
3
- #
3
+
4
4
  module Mina
5
5
  module SshHelpers
6
+
6
7
  # ### ssh
7
8
  # Executes a command via SSH.
8
9
  #
@@ -19,38 +20,21 @@ module Mina
19
20
  # ssh("ls", return: true)
20
21
 
21
22
  def ssh(cmd, options={})
22
- cmd = cmd.join("\n") if cmd.is_a?(Array)
23
-
24
23
  require 'shellwords'
25
24
 
26
- result = 0
25
+ cmd = cmd.join("\n") if cmd.is_a?(Array)
27
26
  script = Shellwords.escape(cmd)
28
27
 
29
28
  if options[:return] == true
30
- result = `#{ssh_command} -- #{script}`
29
+ `#{ssh_command} -- #{script}`
31
30
 
32
31
  elsif simulate_mode?
33
- str = "Executing the following via '#{ssh_command}':"
34
- puts "#!/usr/bin/env bash"
35
- puts "# #{str}"
36
- puts "#"
37
-
38
- puts cmd
32
+ Ssh.simulate(cmd, ssh_command)
39
33
 
40
34
  else
41
- code = "#{ssh_command} -- #{script}"
42
- if settings.term_mode.to_s == 'pretty'
43
- result = pretty_system(code)
44
- elsif settings.term_mode.to_s == 'exec'
45
- exec code
46
- else
47
- system code
48
- result = $?.to_i
49
- end
35
+ result = Ssh.invoke(script, self)
36
+ Ssh.ensure_successful result, self
50
37
  end
51
-
52
- die result if result.is_a?(Fixnum) && result > 0
53
- result
54
38
  end
55
39
 
56
40
  # ### ssh_command
@@ -63,7 +47,7 @@ module Mina
63
47
  # #=> 'ssh diggity@foo.com'
64
48
 
65
49
  def ssh_command
66
- args = domain!
50
+ args = domain!.dup
67
51
  args = "#{user}@#{args}" if user?
68
52
  args << " -i #{identity_file}" if identity_file?
69
53
  args << " -p #{port}" if port?
@@ -72,5 +56,67 @@ module Mina
72
56
  args << " -t"
73
57
  "ssh #{args}"
74
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
+
75
121
  end
76
122
  end
data/lib/mina/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Mina
2
2
  def self.version
3
- "0.2.1"
3
+ "0.3.0"
4
4
  end
5
5
  end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+ require 'command_helper'
3
+
4
+ describe "Invoking the 'mina' command in a project" do
5
+
6
+ it "should build ssh command even with frozen String as a domain" do
7
+ ENV['simulate'] = 'true'
8
+ rake {
9
+ set :domain, 'localhost'.freeze
10
+ ssh("ls")
11
+ }
12
+ end
13
+
14
+ end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'command_helper'
3
+ require 'shellwords'
3
4
 
4
5
  describe "Invoking the 'mina' command in a project" do
5
6
  before :each do
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Mina' do
4
+ it '#invoke should work' do
5
+
6
+ rake {
7
+ task :clone do
8
+ queue 'git clone'
9
+ end
10
+ }
11
+
12
+ 2.times {
13
+ rake { invoke :clone }
14
+ }
15
+
16
+ rake.commands.should == ['git clone']
17
+ end
18
+
19
+ it '#invoke should work with :reenable option' do
20
+
21
+ rake {
22
+ task :pull do
23
+ queue 'git pull'
24
+ end
25
+ }
26
+
27
+ 2.times {
28
+ rake { invoke :pull, :reenable => true }
29
+ }
30
+
31
+ rake.commands.should == ['git pull', 'git pull']
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Output Helpers' do
4
+ before :each do
5
+ @out = Object.new
6
+ @out.send :extend, Mina::OutputHelpers
7
+
8
+ allow(@out).to receive(:print_stdout)
9
+ allow(@out).to receive(:print_status)
10
+ allow(@out).to receive(:print_error)
11
+ allow(@out).to receive(:print_command)
12
+ allow(@out).to receive(:print_clear)
13
+ end
14
+
15
+ it 'print_str to stdout' do
16
+ @out.print_str "Hello there\n"
17
+
18
+ expect(@out).to have_received(:print_stdout).with("Hello there\n")
19
+ end
20
+
21
+ it 'print_str to status' do
22
+ @out.print_str "-----> Getting password"
23
+
24
+ expect(@out).to have_received(:print_status).with("Getting password")
25
+ end
26
+
27
+ it 'print_str to status (2)' do
28
+ @out.print_str "-> Getting password"
29
+
30
+ expect(@out).to have_received(:print_status).with("Getting password")
31
+ end
32
+
33
+ it 'print_str to error' do
34
+ @out.print_str "! Something went wrong"
35
+
36
+ expect(@out).to have_received(:print_error).with("Something went wrong")
37
+ end
38
+ end
data/spec/spec_helper.rb CHANGED
@@ -4,6 +4,7 @@ require 'rake'
4
4
  class RakeScope
5
5
  include Rake::DSL if Rake.const_defined?(:DSL)
6
6
  include Mina::Helpers
7
+ include Mina::SshHelpers
7
8
  end
8
9
 
9
10
  def rake(&blk)
@@ -30,7 +30,7 @@ task :environment do
30
30
  end
31
31
 
32
32
  desc "Deploys."
33
- task :deploy do
33
+ task :deploy => :environment do
34
34
  queue "bundle() { true; }" # Stub the bundle command.
35
35
 
36
36
  deploy do
@@ -61,7 +61,7 @@ namespace :passenger do
61
61
  end
62
62
  end
63
63
 
64
- task :rofl do
64
+ task :get_password do
65
65
  set :term_mode, :pretty
66
- queue %[echo "Password:"; read x; echo out: $x;]
66
+ queue %[echo "-> Getting password"; echo -n "Password: "; read x; echo ""; echo out: $x;]
67
67
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mina
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
5
- prerelease:
4
+ version: 0.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Rico Sta. Cruz
@@ -10,54 +9,48 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2012-09-08 00:00:00.000000000 Z
12
+ date: 2013-07-10 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: rake
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - '>='
21
19
  - !ruby/object:Gem::Version
22
20
  version: '0'
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
25
+ - - '>='
29
26
  - !ruby/object:Gem::Version
30
27
  version: '0'
31
28
  - !ruby/object:Gem::Dependency
32
29
  name: open4
33
30
  requirement: !ruby/object:Gem::Requirement
34
- none: false
35
31
  requirements:
36
- - - ! '>='
32
+ - - '>='
37
33
  - !ruby/object:Gem::Version
38
34
  version: '0'
39
35
  type: :runtime
40
36
  prerelease: false
41
37
  version_requirements: !ruby/object:Gem::Requirement
42
- none: false
43
38
  requirements:
44
- - - ! '>='
39
+ - - '>='
45
40
  - !ruby/object:Gem::Version
46
41
  version: '0'
47
42
  - !ruby/object:Gem::Dependency
48
43
  name: rspec
49
44
  requirement: !ruby/object:Gem::Requirement
50
- none: false
51
45
  requirements:
52
- - - ! '>='
46
+ - - '>='
53
47
  - !ruby/object:Gem::Version
54
48
  version: '0'
55
49
  type: :development
56
50
  prerelease: false
57
51
  version_requirements: !ruby/object:Gem::Requirement
58
- none: false
59
52
  requirements:
60
- - - ! '>='
53
+ - - '>='
61
54
  - !ruby/object:Gem::Version
62
55
  version: '0'
63
56
  description: Really fast deployer and server automation tool.
@@ -72,6 +65,7 @@ files:
72
65
  - .gitignore
73
66
  - .rspec
74
67
  - .travis.yml
68
+ - CONTRIBUTING.md
75
69
  - Gemfile
76
70
  - HISTORY.md
77
71
  - LICENSE
@@ -85,6 +79,8 @@ files:
85
79
  - lib/mina/default.rb
86
80
  - lib/mina/deploy.rb
87
81
  - lib/mina/deploy_helpers.rb
82
+ - lib/mina/exec_helpers.rb
83
+ - lib/mina/foreman.rb
88
84
  - lib/mina/git.rb
89
85
  - lib/mina/helpers.rb
90
86
  - lib/mina/output_helpers.rb
@@ -106,38 +102,40 @@ files:
106
102
  - spec/commands/deploy_spec.rb
107
103
  - spec/commands/outside_project_spec.rb
108
104
  - spec/commands/real_deploy_spec.rb
105
+ - spec/commands/ssh_spec.rb
109
106
  - spec/commands/verbose_spec.rb
107
+ - spec/dsl/invoke_spec.rb
110
108
  - spec/dsl/queue_spec.rb
111
109
  - spec/dsl/settings_in_rake_spec.rb
112
110
  - spec/dsl/settings_spec.rb
113
111
  - spec/dsl/to_spec.rb
114
112
  - spec/fixtures/custom_file_env/custom_deploy.rb
115
113
  - spec/fixtures/empty_env/config/deploy.rb
114
+ - spec/helpers/output_helper_spec.rb
116
115
  - spec/spec_helper.rb
117
116
  - test_env/config/deploy.rb
118
117
  homepage: http://github.com/nadarei/mina
119
118
  licenses: []
119
+ metadata: {}
120
120
  post_install_message:
121
121
  rdoc_options: []
122
122
  require_paths:
123
123
  - lib
124
124
  required_ruby_version: !ruby/object:Gem::Requirement
125
- none: false
126
125
  requirements:
127
- - - ! '>='
126
+ - - '>='
128
127
  - !ruby/object:Gem::Version
129
128
  version: '0'
130
129
  required_rubygems_version: !ruby/object:Gem::Requirement
131
- none: false
132
130
  requirements:
133
- - - ! '>='
131
+ - - '>='
134
132
  - !ruby/object:Gem::Version
135
133
  version: '0'
136
134
  requirements: []
137
135
  rubyforge_project:
138
- rubygems_version: 1.8.23
136
+ rubygems_version: 2.0.2
139
137
  signing_key:
140
- specification_version: 3
138
+ specification_version: 4
141
139
  summary: Really fast deployer and server automation tool.
142
140
  test_files: []
143
141
  has_rdoc: