mina 0.2.1 → 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.
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: