mina 0.3.8 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +16 -0
  3. data/.gitignore +0 -1
  4. data/.rubocop.yml +1156 -0
  5. data/Gemfile +2 -8
  6. data/{CHANGELOG.md → PRE_1_CHANGELOG.md} +0 -0
  7. data/Rakefile +2 -18
  8. data/Readme.md +39 -1116
  9. data/bin/mina +1 -62
  10. data/data/deploy.rb +19 -46
  11. data/data/deploy.sh.erb +22 -23
  12. data/docs/Readme.md +8 -0
  13. data/docs/command_line_options.md +33 -0
  14. data/docs/deploying.md +97 -0
  15. data/docs/faq.md +1 -0
  16. data/docs/getting_started.md +44 -0
  17. data/docs/migrating.md +30 -0
  18. data/docs/writing_your_own_tasks.md +117 -0
  19. data/lib/Minafile +3 -0
  20. data/lib/mina.rb +30 -18
  21. data/lib/mina/application.rb +74 -0
  22. data/lib/mina/backend/local.rb +22 -0
  23. data/lib/mina/backend/remote.rb +42 -0
  24. data/lib/mina/commands.rb +45 -0
  25. data/lib/mina/configuration.rb +36 -0
  26. data/lib/mina/dsl.rb +47 -0
  27. data/lib/mina/helpers/internal.rb +29 -0
  28. data/lib/mina/helpers/output.rb +42 -0
  29. data/lib/mina/runner.rb +39 -0
  30. data/lib/mina/runner/exec.rb +15 -0
  31. data/lib/mina/runner/pretty.rb +53 -0
  32. data/lib/mina/runner/printer.rb +17 -0
  33. data/lib/mina/runner/system.rb +15 -0
  34. data/lib/mina/version.rb +1 -3
  35. data/mina.gemspec +27 -16
  36. data/spec/lib/mina/application_spec.rb +39 -0
  37. data/spec/lib/mina/backend/local_spec.rb +16 -0
  38. data/spec/lib/mina/backend/remote_spec.rb +17 -0
  39. data/spec/lib/mina/commands_spec.rb +93 -0
  40. data/spec/lib/mina/configuration_spec.rb +52 -0
  41. data/spec/lib/mina/helpers/internal_spec.rb +50 -0
  42. data/spec/lib/mina/helpers/output_spec.rb +48 -0
  43. data/spec/lib/mina/runner_spec.rb +36 -0
  44. data/spec/lib/mina_spec.rb +7 -0
  45. data/spec/spec_helper.rb +13 -21
  46. data/spec/support/run_helper.rb +36 -0
  47. data/tasks/mina/bundler.rb +15 -0
  48. data/tasks/mina/chruby.rb +19 -0
  49. data/tasks/mina/default.rb +36 -0
  50. data/tasks/mina/deploy.rb +85 -0
  51. data/tasks/mina/git.rb +36 -0
  52. data/tasks/mina/install.rb +18 -0
  53. data/tasks/mina/rails.rb +108 -0
  54. data/tasks/mina/rbenv.rb +15 -0
  55. data/tasks/mina/rvm.rb +39 -0
  56. data/tasks/mina/ry.rb +26 -0
  57. data/test_env/config/deploy.rb +44 -72
  58. metadata +82 -59
  59. data/.travis.yml +0 -21
  60. data/CONTRIBUTING.md +0 -124
  61. data/HISTORY.md +0 -394
  62. data/Makefile +0 -32
  63. data/Notes.md +0 -70
  64. data/lib/mina/bundler.rb +0 -49
  65. data/lib/mina/chruby.rb +0 -49
  66. data/lib/mina/default.rb +0 -158
  67. data/lib/mina/deploy.rb +0 -160
  68. data/lib/mina/deploy_helpers.rb +0 -34
  69. data/lib/mina/exec_helpers.rb +0 -111
  70. data/lib/mina/foreman.rb +0 -83
  71. data/lib/mina/git.rb +0 -69
  72. data/lib/mina/helpers.rb +0 -408
  73. data/lib/mina/local_helpers.rb +0 -97
  74. data/lib/mina/npm.rb +0 -89
  75. data/lib/mina/output_helpers.rb +0 -92
  76. data/lib/mina/rails.rb +0 -245
  77. data/lib/mina/rake.rb +0 -10
  78. data/lib/mina/rbenv.rb +0 -47
  79. data/lib/mina/rvm.rb +0 -88
  80. data/lib/mina/ry.rb +0 -55
  81. data/lib/mina/settings.rb +0 -32
  82. data/lib/mina/ssh_helpers.rb +0 -125
  83. data/lib/mina/tools.rb +0 -20
  84. data/lib/mina/whenever.rb +0 -51
  85. data/manual/index.md +0 -15
  86. data/manual/modules.md +0 -2
  87. data/spec/command_helper.rb +0 -52
  88. data/spec/commands/cleanup_spec.rb +0 -16
  89. data/spec/commands/command_spec.rb +0 -71
  90. data/spec/commands/custom_config_spec.rb +0 -20
  91. data/spec/commands/deploy_spec.rb +0 -40
  92. data/spec/commands/outside_project_spec.rb +0 -35
  93. data/spec/commands/real_deploy_spec.rb +0 -56
  94. data/spec/commands/ssh_spec.rb +0 -14
  95. data/spec/commands/verbose_spec.rb +0 -21
  96. data/spec/dsl/invoke_spec.rb +0 -49
  97. data/spec/dsl/queue_spec.rb +0 -49
  98. data/spec/dsl/settings_in_rake_spec.rb +0 -39
  99. data/spec/dsl/settings_spec.rb +0 -61
  100. data/spec/dsl/to_spec.rb +0 -20
  101. data/spec/fixtures/custom_file_env/custom_deploy.rb +0 -15
  102. data/spec/fixtures/empty_env/config/deploy.rb +0 -15
  103. data/spec/helpers/exec_helper_spec.rb +0 -19
  104. data/spec/helpers/local_helper_spec.rb +0 -70
  105. data/spec/helpers/output_helper_spec.rb +0 -38
  106. data/support/Readme-footer.md +0 -31
  107. data/support/Readme-header.md +0 -16
  108. data/support/guide.md +0 -297
  109. data/support/index.html +0 -53
  110. data/support/third_party_modules.md +0 -23
  111. data/support/to_md.rb +0 -11
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mina::Configuration do
4
+ let(:config) { Class.new(Mina::Configuration).instance }
5
+ let(:key) { config.fetch(:key, :default) }
6
+
7
+ describe '#set' do
8
+ it 'sets by value' do
9
+ config.set(:key, :value)
10
+ expect(key).to eq :value
11
+ end
12
+
13
+ it 'sets by block' do
14
+ config.set(:key) { :value }
15
+ expect(key).to eq :value
16
+ end
17
+ end
18
+
19
+ describe '#fetch' do
20
+ it 'returns the default value if key not set' do
21
+ expect(key).to eq :default
22
+ end
23
+
24
+ it 'returns ENV value if set' do
25
+ ENV['key'] = 'env'
26
+ expect(key).to eq 'env'
27
+ ENV['key'] = nil
28
+ end
29
+ end
30
+
31
+ describe '#set?' do
32
+ it 'returns true if key is set' do
33
+ config.set(:key, :value)
34
+ expect(config.set?(:key)).to be true
35
+ end
36
+
37
+ it 'returns false if key is not set' do
38
+ expect(config.set?(:key)).to be false
39
+ end
40
+ end
41
+
42
+ describe '#ensure!' do
43
+ it 'does not raise error if key is set' do
44
+ config.set(:key, :value)
45
+ expect { config.ensure!(:key) }.to_not raise_error
46
+ end
47
+
48
+ it 'raises an error if key is not set' do
49
+ expect { config.ensure!(:key) }.to raise_error(StandardError)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mina::Helpers::Internal do
4
+ class DummyInternalHelper
5
+ include Mina::DSL
6
+ include Mina::Helpers::Internal
7
+ end
8
+
9
+ let(:helper) { DummyInternalHelper.new }
10
+
11
+ describe '#deploy_script' do
12
+ before { Mina::Configuration.instance.set(:deploy_script, 'data/deploy.sh.erb') }
13
+
14
+ it 'returns whole script' do
15
+ expect(helper.deploy_script {}).to_not be_empty
16
+ end
17
+ end
18
+
19
+ describe '#erb' do
20
+ it 'returns whole script' do
21
+ expect(helper.erb('data/deploy.sh.erb')).to_not be_empty
22
+ end
23
+ end
24
+
25
+ describe '#echo_cmd' do
26
+ context 'when not verbose' do
27
+ it 'reuturns unedited code' do
28
+ expect(helper.echo_cmd('ls -al')).to eq('ls -al')
29
+ end
30
+ end
31
+
32
+ context 'when verbose' do
33
+ before { Mina::Configuration.instance.set(:verbose, true) }
34
+
35
+ it 'modifies code' do
36
+ expect(helper.echo_cmd('ls -al')).to eq("echo \\$\\ ls\\ -al &&\nls -al")
37
+ end
38
+
39
+ it 'does not modify code if ignore_verbose is true' do
40
+ expect(helper.echo_cmd('ls -al', ignore_verbose: true)).to eq('ls -al')
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#indent' do
46
+ it 'indents code' do
47
+ expect(helper.indent(4, 'ls -al')).to eq(' ls -al')
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mina::Helpers::Output do
4
+ class DummyOutputHelper
5
+ include Mina::Helpers::Output
6
+ end
7
+
8
+ let(:helper) { DummyOutputHelper.new }
9
+
10
+ describe '#print_line' do
11
+ it 'prints normally' do
12
+ out, _err = capture_io do
13
+ helper.print_line('ls -al')
14
+ end
15
+ expect(out).to eq(" ls -al\n")
16
+ end
17
+
18
+ it 'prints comment' do
19
+ out, _err = capture_io do
20
+ helper.print_line('-> ls -al')
21
+ end
22
+ expect(out).to eq("\e[32m----->\e[0m ls -al\n")
23
+ end
24
+
25
+ it 'prints error' do
26
+ out, _err = capture_io do
27
+ helper.print_line('! ls -al')
28
+ end
29
+ expect(out).to eq(" \e[33m!\e[0m \e[31mls -al\e[0m\n")
30
+ end
31
+
32
+ it 'prints command' do
33
+ out, _err = capture_io do
34
+ helper.print_line('$ ls -al')
35
+ end
36
+ expect(out).to eq(" \e[36m$\e[0m \e[36mls -al\e[0m\n")
37
+ end
38
+ end
39
+
40
+ describe '#print_stderr' do
41
+ it 'prints stderr' do
42
+ out, _err = capture_io do
43
+ helper.print_stderr('ls -al')
44
+ end
45
+ expect(out).to eq(" \e[31mls -al\e[0m\n")
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mina::Runner do
4
+ let(:instance) { Mina::Configuration.instance }
5
+
6
+ describe '#initialize' do
7
+ it 'raises an error if execution mode is not set' do
8
+ instance.remove(:execution_mode)
9
+ expect { Mina::Runner.new(nil, nil) }.to raise_error('You must specify execution mode')
10
+ end
11
+
12
+ it 'raises an error when run on windows and pretty print' do
13
+ instance.set(:execution_mode, :pretty)
14
+ allow(Gem::Platform.local).to receive(:os).and_return(:windows)
15
+ expect { Mina::Runner.new(nil, nil) }.to raise_error('Unsuported execution mode (pretty on windows)')
16
+ end
17
+
18
+ it 'sets execution mode to printer if simulate is true' do
19
+ instance.set(:execution_mode, :pretty)
20
+ instance.set(:simulate, :true)
21
+ expect(Mina::Runner.new(nil, nil).execution_mode).to eq(:printer)
22
+ instance.remove(:simulate)
23
+ end
24
+ end
25
+
26
+ describe '#run' do
27
+ it 'runs the commands on a backend' do
28
+ instance.set(:execution_mode, :printer)
29
+ runner = Mina::Runner.new(['ls -al'], :local)
30
+ out, _err = capture_io do
31
+ runner.run
32
+ end
33
+ expect(out).to eq("\\[\\\"ls\\ -al\\\"\\]\n")
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ module Mina
4
+ describe Application do
5
+ let(:app) { Application.new }
6
+ end
7
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,28 +1,20 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
1
4
  require 'mina'
2
- require 'rake'
5
+ require 'rspec'
6
+ require 'codeclimate-test-reporter'
7
+ CodeClimate::TestReporter.start
8
+
9
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
3
10
 
4
11
  RSpec.configure do |config|
5
- config.order = 'random'
6
- config.seed = '12345'
7
- end
12
+ config.include RunHelper
8
13
 
9
- class RakeScope
10
- include Rake::DSL if Rake.const_defined?(:DSL)
11
- include Mina::Helpers
12
- include Mina::SshHelpers
13
- include Mina::LocalHelpers
14
- end
14
+ config.raise_errors_for_deprecations!
15
+ config.order = 'random'
15
16
 
16
- def rake(&blk)
17
- if block_given?
18
- @scope ||= RakeScope.new
19
- @scope.instance_eval &blk
17
+ config.after(:each) do
18
+ Mina::Configuration.instance.reset!
20
19
  end
21
-
22
- @scope
23
20
  end
24
-
25
- def root(*a)
26
- File.join File.expand_path('../../', __FILE__), *a
27
- end
28
-
@@ -0,0 +1,36 @@
1
+ module RunHelper
2
+ def flags(*sets)
3
+ sets.each do |set|
4
+ ARGV.clear
5
+ @exit = catch(:system_exit) { command_line(*set) }
6
+ end
7
+ yield(subject.options) if block_given?
8
+ end
9
+
10
+ def command_line(*options)
11
+ options.each { |opt| ARGV << opt }
12
+ subject.define_singleton_method(:exit) do |*_args|
13
+ throw(:system_exit, :exit)
14
+ end
15
+ subject.run
16
+ subject.options
17
+ end
18
+
19
+ def capture_io
20
+ require 'stringio'
21
+
22
+ orig_stdout = $stdout
23
+ orig_stderr = $stderr
24
+ captured_stdout = StringIO.new
25
+ captured_stderr = StringIO.new
26
+ $stdout = captured_stdout
27
+ $stderr = captured_stderr
28
+
29
+ yield
30
+
31
+ return captured_stdout.string, captured_stderr.string
32
+ ensure
33
+ $stdout = orig_stdout
34
+ $stderr = orig_stderr
35
+ end
36
+ end
@@ -0,0 +1,15 @@
1
+ require 'mina/default'
2
+
3
+ set :bundle_bin, 'bundle'
4
+ set :bundle_path, 'vendor/bundle'
5
+ set :bundle_withouts, 'development:test'
6
+ set :bundle_options, -> { "--without #{fetch(:bundle_withouts)} --path '#{fetch(:bundle_path)}' --deployment" }
7
+ set :shared_dirs, fetch(:shared_dirs, []).push(fetch(:bundle_path))
8
+
9
+ namespace :bundle do
10
+ desc 'Install gem dependencies using Bundler.'
11
+ task install: :environment do
12
+ comment 'Installing gem dependencies using Bundler'
13
+ command "#{fetch(:bundle_bin)} install #{fetch(:bundle_options)}"
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ set :chruby_path, '/etc/profile.d/chruby.sh'
2
+
3
+ task :chruby, :env do |_, args|
4
+ unless args[:env]
5
+ print_error "Task 'chruby' needs a Ruby version as an argument."
6
+ print_error "Example: invoke :'chruby[ruby-1.9.3-p392]'"
7
+ die
8
+ end
9
+
10
+ comment "chruby to version: '#{args[:env]}'"
11
+ command %(
12
+ if [[ ! -s "#{fetch(:chruby_path)}" ]]; then
13
+ echo "! chruby.sh init file not found"
14
+ exit 1
15
+ fi
16
+ )
17
+ command "source #{fetch(:chruby_path)}"
18
+ command "chruby '#{args[:env]}' || exit 1"
19
+ end
@@ -0,0 +1,36 @@
1
+ task :environment do
2
+ end
3
+
4
+ task run_commands: :environment do
5
+ commands.run(:remote) unless commands.queue.empty?
6
+ end
7
+
8
+ task debug_configuration_variables: :environment do
9
+ if fetch(:debug_configuration_variables)
10
+ puts
11
+ puts '------- Printing current config variables -------'
12
+ configuration.variables.each do |key, value|
13
+ puts "#{key.inspect} => #{value.inspect}"
14
+ end
15
+ end
16
+ end
17
+
18
+ desc 'Runs a command in the server.'
19
+ task :run, [:command] => [:environment] do |_, args|
20
+ ensure!(:deploy_to)
21
+ command = args[:command]
22
+
23
+ unless command
24
+ puts "You need to provide a command. Try: mina 'run[ls -la]'"
25
+ exit 1
26
+ end
27
+
28
+ in_path fetch(:deploy_to) do
29
+ command command
30
+ end
31
+ end
32
+
33
+ desc 'Open an ssh session to the server and cd to deploy_to folder'
34
+ task ssh: :environment do
35
+ exec ssh_command + " 'cd #{deploy_to} && exec \$SHELL'"
36
+ end
@@ -0,0 +1,85 @@
1
+ require 'mina/default'
2
+
3
+ set :releases_path, -> { "#{fetch(:deploy_to)}/releases" }
4
+ set :shared_path, -> { "#{fetch(:deploy_to)}/shared" }
5
+ set :current_path, -> { "#{fetch(:deploy_to)}/current" }
6
+ set :lock_file, 'deploy.lock'
7
+ set :deploy_script, 'data/deploy.sh.erb'
8
+ set :keep_releases, 5
9
+ set :execution_mode, :pretty
10
+
11
+ namespace :deploy do
12
+ desc 'Forces a deploy unlock.'
13
+ task force_unlock: :environment do
14
+ comment 'Unlocking'
15
+ command "rm -f '#{fetch(:deploy_to)}/#{fetch(:lock_file)}'"
16
+ end
17
+
18
+ desc 'Links paths set in :shared_dirs and :shared_files.'
19
+ task link_shared_paths: :environment do
20
+ comment 'Symlinking shared paths'
21
+
22
+ fetch(:shared_dirs, []).each do |linked_dir|
23
+ command %(mkdir -p #{File.dirname("./#{linked_dir}")})
24
+ command "rm -rf './#{linked_dir}'"
25
+ command "ln -s '#{fetch(:shared_path)}/#{linked_dir}' './#{linked_dir}'"
26
+ end
27
+
28
+ fetch(:shared_files, []).each do |linked_path|
29
+ command "ln -s '#{fetch(:shared_path)}/#{linked_path}' './#{linked_path}'"
30
+ end
31
+ end
32
+
33
+ desc 'Clean up old releases.'
34
+ task cleanup: :environment do
35
+ ensure!(:keep_releases)
36
+ ensure!(:deploy_to)
37
+
38
+ comment "Cleaning up old releases (keeping #{fetch(:keep_releases)})"
39
+ in_path "#{fetch(:releases_path)}" do
40
+ command 'count=`ls -1 | sort -rn | wc -l`'
41
+ command "remove=$((count > #{fetch(:keep_releases)} ? $count - #{fetch(:keep_releases)} : 0))"
42
+ command 'ls -1 | sort -rn | tail -n $remove | xargs rm -rf {}'
43
+ end
44
+ end
45
+ end
46
+
47
+ # TODO: Test this
48
+ # desc 'Rollbacks the latest release'
49
+ # task rollback: :environment do
50
+ # comment "Rolling back to previous release for instance: #{fetch(:domain)}"
51
+ #
52
+ # # Delete existing sym link and create a new symlink pointing to the previous release
53
+ # comment 'Creating new symlink from the previous release: '
54
+ # command "ls -Art '#{fetch(:releases_path)}' | sort | tail -n 2 | head -n 1"
55
+ # command "ls -Art '#{fetch(:releases_path)}' | sort | tail -n 2 | head -n 1 | xargs -I active ln -nfs '#{fetch(:releases_path)}/active' '#{fetch(:current_path)}'"
56
+ #
57
+ # # Remove latest release folder (current release)
58
+ # comment 'Deleting current release: '
59
+ # command "ls -Art '#{fetch(:releases_path)}' | sort | tail -n 1"
60
+ # command "ls -Art '#{fetch(:releases_path)}' | sort | tail -n 1 | xargs -I active rm -rf '#{fetch(:releases_path)}/active'"
61
+ # end
62
+ # end
63
+
64
+ desc 'Sets up a site.'
65
+ task setup: :environment do
66
+ ensure!(:deploy_to)
67
+
68
+ comment "Setting up #{fetch(:deploy_to)}"
69
+ command "mkdir -p '#{fetch(:deploy_to)}'"
70
+ command "chown -R `whoami` '#{fetch(:deploy_to)}'"
71
+ command "chmod g+rx,u+rwx '#{fetch(:deploy_to)}'"
72
+ command "mkdir -p '#{fetch(:releases_path)}'"
73
+ command "chmod g+rx,u+rwx '#{fetch(:releases_path)}'"
74
+ command "mkdir -p '#{fetch(:shared_path)}'"
75
+ command "chmod g+rx,u+rwx '#{fetch(:shared_path)}'"
76
+
77
+ in_path "#{fetch(:shared_path)}" do
78
+ fetch(:shared_dirs, []).each do |linked_dir|
79
+ command "mkdir -p '#{linked_dir}'"
80
+ command "chmod g+rx,u+rwx '#{linked_dir}'"
81
+ end
82
+ end
83
+
84
+ command "tree '#{fetch(:deploy_to)}' || ls -al '#{fetch(:deploy_to)}'"
85
+ end
data/tasks/mina/git.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'mina/default'
2
+
3
+ set :branch, 'master'
4
+
5
+ namespace :git do
6
+ desc 'Clones the Git repository to the release path.'
7
+ task clone: :environment do
8
+ ensure!(:repository)
9
+ ensure!(:deploy_to)
10
+ if set?(:commit)
11
+ comment "Using git commit '#{fetch(:commit)}'"
12
+ command "git clone '#{fetch(:repository)}' . --recursive"
13
+ command "git checkout -b current_release '#{fetch(:commit)}' --force"
14
+ else
15
+ command %(if [ ! -d "#{fetch(:deploy_to)}/scm/objects" ]; then
16
+ echo "-----> Cloning the Git repository"
17
+ #{echo_cmd %[git clone "#{fetch(:repository)}" "#{fetch(:deploy_to)}/scm" --bare]}
18
+ else
19
+ echo "-----> Fetching new git commits"
20
+ #{echo_cmd %[(cd "#{fetch(:deploy_to)}/scm" && git fetch "#{fetch(:repository)}" "#{fetch(:branch)}:#{fetch(:branch)}" --force)]}
21
+ fi &&
22
+ echo "-----> Using git branch '#{fetch(:branch)}'" &&
23
+ #{echo_cmd %[git clone "#{fetch(:deploy_to)}/scm" . --recursive --branch "#{fetch(:branch)}"]}), quiet: true
24
+ end
25
+
26
+ comment 'Using this git commit'
27
+ command 'git rev-parse HEAD > .mina_git_revision'
28
+ command "git --no-pager log --format='%aN (%h):%n> %s' -n 1"
29
+ command 'rm -rf .git'
30
+ end
31
+
32
+ task revision: :environment do
33
+ ensure!(:deploy_to)
34
+ command "cat #{fetch(:current_path)}/.mina_git_revision"
35
+ end
36
+ end