mina 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ require 'bundler'
2
+ require 'bundler/gem_tasks'
3
+
4
+ # Do these:
5
+ #
6
+ # *do `gem install reacco`
7
+ # * install http://github.com/rstacruz/git-update-ghpages
8
+
9
+ ENV['github'] ||= 'nadarei/mina'
10
+
11
+ namespace :doc do
12
+
13
+ task :build do
14
+ cmd = "reacco --literate --toc --github #{ENV['github']}"
15
+ cmd << " --analytics=#{ENV['analytics_id']}" if ENV['analytics_id']
16
+
17
+ system cmd
18
+ raise "Failed" unless $?.to_i == 0
19
+ end
20
+
21
+
22
+ desc "Updates online documentation"
23
+ task :deploy => :build do
24
+ system "git update-ghpages #{ENV['github']} -i doc"
25
+ end
26
+ end
27
+
28
+ task :spec do
29
+ system "rm Gemfile.lock; sh -c 'rake=0.8 bundle exec rspec'"
30
+ system "rm Gemfile.lock; sh -c 'rake=0.9 bundle exec rspec'"
31
+ end
32
+
33
+ task :default => :spec
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path('../../lib', __FILE__)
3
+
4
+ require 'rubygems' unless Object.const_defined?(:Gem)
5
+ require 'mina'
6
+ require 'rake'
7
+
8
+ # Intercept: if invoked as 'mina --help', don't let it pass through Rake, or else
9
+ # we'll see the Rake help screen. Redirect it to 'mina help'.
10
+ if ARGV.delete('--help') || ARGV.delete('-h')
11
+ ARGV << 'help'
12
+ end
13
+
14
+ if ARGV.delete('--version') || ARGV.delete('-V')
15
+ puts "Mina, version v#{Mina.version}"
16
+ exit
17
+ end
18
+
19
+ if ARGV.delete('--simulate') || ARGV.delete('-S')
20
+ ENV['simulate'] = '1'
21
+ end
22
+
23
+ scope = self
24
+
25
+ Rake.application.instance_eval do
26
+ standard_exception_handling do
27
+ # Initialize Rake and make it think it's Mina.
28
+ init 'mina'
29
+ @rakefiles = ['Minafile', 'config/deploy.rb']
30
+
31
+ # Workaround: Rake 0.9+ doesn't record task descriptions unless it's needed.
32
+ # Need it for 'mina help'
33
+ if Rake::TaskManager.respond_to?(:record_task_metadata)
34
+ Rake::TaskManager.record_task_metadata = true
35
+ end
36
+
37
+ # Load the Mina Rake DSL.
38
+ require 'mina/rake'
39
+
40
+ # Allow running without a Rakefile
41
+ load_rakefile if have_rakefile
42
+
43
+ # Run tasks
44
+ top_level
45
+
46
+ scope.mina_cleanup! if top_level_tasks.any?
47
+ end
48
+ end
49
+
@@ -0,0 +1,30 @@
1
+ require 'mina/bundler'
2
+ require 'mina/rails'
3
+ require 'mina/git'
4
+
5
+ # Basic settings:
6
+ # host - The hostname to SSH to
7
+ # deploy_to - Path to deploy into
8
+ # repository - Git repo to clone from (needed by mina/git)
9
+ # user - Username in the server to SSH to (optional)
10
+
11
+ set :host, 'foobar.com'
12
+ set :deploy_to, '/var/www/foobar.com'
13
+ set :repository, 'git://...'
14
+ # set :user, 'foobar.com'
15
+
16
+ desc "Deploys the current version to the server."
17
+ task :deploy do
18
+ deploy do
19
+ # Put things that will set up an empty directory into a fully set-up
20
+ # instance of your project.
21
+ invoke :'git:checkout'
22
+ invoke :'bundle:install'
23
+ invoke :'rails:db_migrate'
24
+ invoke :'rails:assets_precompile'
25
+
26
+ to :launch do
27
+ queue 'touch tmp/restart.txt'
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,98 @@
1
+ <%
2
+ prepare = commands(:default).map { |s| "(\n\n#{indent 2, s}\n\n)" }.join(" && ")
3
+ launch = commands(:launch).map { |s| "(\n\n#{indent 2, s}\n\n)" }.join(" && ")
4
+ clean = commands(:clean).map { |s| "(\n\n#{indent 2, s}\n\n)" }.join(" && ")
5
+ %>
6
+ #!/usr/bin/env bash
7
+
8
+ # Go to the deploy path
9
+ cd "<%= deploy_to %>" || (
10
+ echo "=====> ERROR: not set up."
11
+ echo "The path '<%= deploy_to %>' is not accessible on the server."
12
+ echo "You may need to run 'mina setup' first."
13
+ false
14
+ ) || exit 16
15
+
16
+ # Check lockfile
17
+ if [ -e "<%= lock_file %>" ]; then
18
+ echo "=====> ERROR: another deployment is ongoing."
19
+ echo "The file '<%= lock_file %>' was found."
20
+ echo "If no other deployment is ongoing, delete the file to continue."
21
+ exit 17
22
+ fi
23
+
24
+ # Determine $previous_path and other variables
25
+ [ -h "<%= current_path %>" ] && [ -d "<%= current_path %>" ] && previous_path=$(cd "<%= current_path %>" >/dev/null && pwd -LP)
26
+ build_path="./tmp/build-`date +%s`$RANDOM"
27
+ version=$((`cat "<%= deploy_to %>/last_version" 2>/dev/null`+1))
28
+ release_path="<%= releases_path %>/$version"
29
+
30
+ # Sanity check
31
+ if [ -e "$build_path" ]; then
32
+ echo "=====> ERROR: Path already exists"
33
+ exit 18
34
+ fi
35
+
36
+ # Bootstrap script (in deployer)
37
+ (
38
+ echo "-----> Creating a temporary build path"
39
+ <%= echo_cmd %[touch "#{lock_file}"] %> &&
40
+ <%= echo_cmd %[mkdir -p "$build_path"] %> &&
41
+ <%= echo_cmd %[cd "$build_path"] %> &&
42
+ (
43
+ <%= indent 4, (prepare.empty? ? "true" : prepare) %>
44
+ )
45
+ ) &&
46
+
47
+ #
48
+ # Rename to the real release path, then symlink 'current'
49
+ (
50
+ echo "-----> Build finished"
51
+ echo "-----> Moving build to $release_path"
52
+ <%= echo_cmd %[mv "$build_path" "$release_path"] %> &&
53
+
54
+ echo "-----> Updating the <%= current_path %> symlink" &&
55
+ <%= echo_cmd %[ln -nfs "$release_path" "#{current_path}"] %>
56
+ ) &&
57
+
58
+ # ============================
59
+ # === Start up serve => (in deployer)
60
+ (
61
+ echo "-----> Launching"
62
+ <%= echo_cmd %[cd "$release_path"] %>
63
+ <%= indent 2, (launch.empty? ? "true" : launch) %>
64
+ ) &&
65
+
66
+ # ============================
67
+ # === Complete & unlock
68
+ (
69
+ rm -f "<%= lock_file %>"
70
+ echo "$version" > "./last_version"
71
+ echo "-----> Done. Deployed v$version"
72
+ ) ||
73
+
74
+ # ============================
75
+ # === Failed deployment
76
+ (
77
+ echo "=====> ERROR: Deploy failed."
78
+
79
+ <%= indent 2, clean %>
80
+
81
+ echo "-----> Cleaning up build"
82
+ [ -e "$build_path" ] && (
83
+ <%= echo_cmd %[rm -rf "$build_path"] %>
84
+ )
85
+ [ -e "$release_path" ] && (
86
+ echo "Deleting release"
87
+ <%= echo_cmd %[rm -rf "$release_path"] %>
88
+ )
89
+ (
90
+ echo "Unlinking current"
91
+ [ -n "$previous_path" ] && <%= echo_cmd %[ln -nfs "$previous_path" "#{current_path}"] %>
92
+ )
93
+
94
+ # Unlock
95
+ <%= echo_cmd %[rm -f "#{lock_file}"] %>
96
+ echo "OK"
97
+ exit 8
98
+ )
@@ -0,0 +1,20 @@
1
+ module Mina
2
+ PREFIX = File.dirname(__FILE__)
3
+ ROOT = File.expand_path('../../', __FILE__)
4
+
5
+ require 'mina/version'
6
+
7
+ autoload :DeployHelpers, 'mina/deploy_helpers'
8
+ autoload :Helpers, 'mina/helpers'
9
+ autoload :Settings, 'mina/settings'
10
+ autoload :Tools, 'mina/tools'
11
+
12
+ Error = Class.new(Exception)
13
+ class Failed < Error
14
+ attr_accessor :exitstatus
15
+ end
16
+
17
+ def self.root_path(*a)
18
+ File.join ROOT, *a
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+
2
+ settings.bundle_path ||= './vendor/bundle'
3
+ settings.bundle_options ||= lambda { %{--without development:test --path "#{bundle_path}" --binstubs bin/ --deployment} }
4
+
5
+ namespace :bundle do
6
+ desc "Install gem dependencies using Bundler."
7
+ task :install do
8
+ if bundle_path.nil?
9
+ queue %{
10
+ echo "-----> Installing gem dependencies using Bundler"
11
+ #{echo_cmd %[bundle install #{bundle_options}]}
12
+ }
13
+ else
14
+ queue %{
15
+ echo "-----> Installing gem dependencies using Bundler"
16
+ #{echo_cmd %[mkdir -p "#{deploy_to}/#{shared_path}/bundle"]}
17
+ #{echo_cmd %[mkdir -p "#{File.dirname bundle_path}"]}
18
+ #{echo_cmd %[ln -s "#{deploy_to}/#{shared_path}/bundle" "#{bundle_path}"]}
19
+ #{echo_cmd %[bundle install #{bundle_options}]}
20
+ }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,97 @@
1
+ set_default :term_mode, nil
2
+
3
+ # Default tasks here
4
+ desc "Creates a sample config file."
5
+ task :init do
6
+ name = Rake.application.name
7
+ config_file = Rake.application.rakefile
8
+
9
+ unless config_file.to_s.empty?
10
+ error "You already have #{config_file}."
11
+ exit 8
12
+ end
13
+
14
+ require 'fileutils'
15
+ FileUtils.mkdir_p './config'
16
+ FileUtils.cp Mina.root_path('data/deploy.rb'), './config/deploy.rb'
17
+
18
+ puts 'Created deploy.rb.'
19
+ puts 'Edit it, then run `#{name} setup` after.'
20
+ end
21
+
22
+ task :default => :help
23
+
24
+ module HelpHelpers
25
+ def get_tasks(&blk)
26
+ Rake.application.tasks.select &blk
27
+ end
28
+
29
+ def print_tasks(tasks, width=nil)
30
+ name = Rake.application.name
31
+
32
+ width ||= tasks.map { |t| t.name_with_args.length }.max || 10
33
+ tasks.each do |t|
34
+ if t.comment
35
+ puts " #{name} %-#{width}s # %s" % [ t.name_with_args, t.comment ]
36
+ else
37
+ puts " #{name} %s" % [ t.name_with_args ]
38
+ end
39
+ end
40
+ end
41
+
42
+ SYSTEM_TASKS = %w[help tasks init]
43
+ def system_tasks() get_tasks { |t| SYSTEM_TASKS.include? t.name }; end
44
+ def top_tasks() get_tasks { |t| ! t.name.include?(':') && t.comment && !system_tasks.include?(t) }; end
45
+ def sub_tasks() get_tasks { |t| t.name.include?(':') }; end
46
+
47
+ def show_task_help(options={})
48
+ puts "Basic usage:"
49
+ print_tasks system_tasks
50
+
51
+ if top_tasks.any?
52
+ puts "\nServer tasks:"
53
+ print_tasks top_tasks
54
+ end
55
+
56
+ if sub_tasks.any? && options[:full]
57
+ puts "\nMore tasks:"
58
+ print_tasks sub_tasks
59
+ end
60
+ end
61
+ end
62
+
63
+ extend HelpHelpers
64
+
65
+ desc "Show help."
66
+ task :help do
67
+ name = Rake.application.name
68
+
69
+ puts "#{name} - Really fast server deployment and automation tool\n\n"
70
+ puts "Options:"
71
+
72
+ opts = [
73
+ [ "-h, --help", "Show help" ],
74
+ [ "-V, --version", "Show program version" ],
75
+ [ "-v, --verbose", "Show commands as they happen" ],
76
+ [ "-S, --simulate", "Run in simulation mode" ],
77
+ [ "-t, --trace", "Show backtraces when errors occur" ]
78
+ ]
79
+ opts.each { |args| puts " %-17s %s" % args }
80
+ puts ""
81
+
82
+ show_task_help
83
+
84
+ unless Rake.application.have_rakefile
85
+ puts ""
86
+ puts "Run this command in a project with a 'config/deploy.rb' file to see more options."
87
+ end
88
+
89
+ puts ""
90
+ puts "All of Rake's options are also available as '#{name}' options. See 'rake --help'"
91
+ puts "for more information."
92
+ end
93
+
94
+ desc "Show all tasks."
95
+ task :tasks do
96
+ show_task_help :full => true
97
+ end
@@ -0,0 +1,57 @@
1
+ set_default :releases_path, "releases"
2
+ set_default :shared_path, "shared"
3
+ set_default :current_path, "current"
4
+ set_default :lock_file, "deploy.lock"
5
+
6
+ namespace :deploy do
7
+ desc "Forces a deploy unlock."
8
+ task :force_unlock do
9
+ queue %{echo "-----> Unlocking"}
10
+ queue echo_cmd %{rm -f "#{deploy_to}/#{lock_file}"}
11
+ end
12
+
13
+ desc "Links paths set in :shared_paths."
14
+ task :link_shared_paths do
15
+ dirs = settings.shared_paths!.map { |file| File.dirname("./#{file}") }.uniq
16
+
17
+ cmds = dirs.map do |dir|
18
+ echo_cmd %{mkdir -p "#{dir}"}
19
+ end
20
+
21
+ cmds += shared_paths.map do |file|
22
+ echo_cmd %{ln -s "#{shared_path}/#{file}" "./#{file}"}
23
+ end
24
+
25
+ queue %{
26
+ echo "-----> Symlinking shared paths"
27
+ #{cmds.join(" &&\n")}
28
+ }
29
+ end
30
+ end
31
+
32
+ desc "Sets up a site."
33
+ task :setup do
34
+ settings.deploy_to!
35
+
36
+ queue %{echo "-----> Setting up #{deploy_to}"}
37
+ queue echo_cmd %{mkdir -p "#{deploy_to}"}
38
+ queue echo_cmd %{chown -R `whoami` "#{deploy_to}"}
39
+ queue echo_cmd %{chmod g+rx,u+rwx "#{deploy_to}"}
40
+ queue echo_cmd %{cd "#{deploy_to}"}
41
+ queue echo_cmd %{mkdir -p "#{releases_path}"}
42
+ queue echo_cmd %{chmod g+rx,u+rwx "#{releases_path}"}
43
+ queue echo_cmd %{mkdir -p "#{shared_path}"}
44
+ queue echo_cmd %{chmod g+rx,u+rwx "#{shared_path}"}
45
+ queue %{echo "-----> Done"}
46
+ end
47
+
48
+ desc "Runs a command in the server."
49
+ task :run, :command do |t, args|
50
+ command = args[:command]
51
+ unless command
52
+ puts %[You need to provide a command. Try: mina "run[ls -la]"]
53
+ exit 1
54
+ end
55
+
56
+ queue %[cd #{deploy_to!} && #{command}]
57
+ end
@@ -0,0 +1,25 @@
1
+ module Mina
2
+ module DeployHelpers
3
+ # Wraps the things inside it in a deploy script, and queues it.
4
+ # This generates a script using deploy_script and queues it.
5
+ def deploy(&blk)
6
+ queue deploy_script(&blk)
7
+ end
8
+
9
+ # Wraps the things inside it in a deploy script.
10
+ #
11
+ # script = deploy_script do
12
+ # invoke :'git:checkout'
13
+ # end
14
+ #
15
+ # queue script
16
+ #
17
+ def deploy_script(&blk)
18
+ set_default :term_mode, :pretty
19
+ code = isolate do
20
+ yield
21
+ erb Mina.root_path('data/deploy.sh.erb')
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ namespace :git do
2
+ desc "Clones the Git repository to the release path."
3
+ task :clone do
4
+ settings.revision ||= `git rev-parse HEAD`.strip
5
+
6
+ queue %{
7
+ echo "-----> Cloning the Git repository"
8
+ #{echo_cmd %[git clone "#{repository!}" . -n --recursive]} &&
9
+ echo "-----> Using revision #{revision}" &&
10
+ #{echo_cmd %[git checkout "#{revision}" -b current_release 1>/dev/null]} &&
11
+ #{echo_cmd %[rm -rf .git]}
12
+ }
13
+ end
14
+ end