Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

support for gems as external dependencies

  • Loading branch information...
commit d88a43b9b100fec71d8f2d86d85c0df353ca660f 1 parent 9f41c21
@jamis jamis authored
Showing with 90 additions and 28 deletions.
  1. +4 −1 README.rdoc
  2. +86 −27 recipes/cached_externals.rb
View
5 README.rdoc
@@ -18,7 +18,7 @@ This means your deploys only have to add a single symbolic link for each externa
== Assumptions
-The Cached Externals plugin assumes that your external dependencies are under version control somewhere, and the repositories are accessible both locally and from your deployment targets.
+The Cached Externals plugin assumes that your external dependencies are either a gem, or under version control somewhere, and the gem sources and repositories are accessible both locally and from your deployment targets.
== Usage
@@ -41,6 +41,9 @@ Next, tell Capistrano about your external dependencies. This is done via a YAML
:type: git
:repository: git://github.com/rails/exception_notification.git
:revision: ed0b914ff493f9137abc4f68ee08e3c3cd7a3211
+ vendor/libs/tzinfo:
+ :type: gem
+ :version: 0.3.18
Specify as many as you like. Although it is best to specify an exact revision, you can also give any revision identifier that capistrano understands (git branches, HEAD, etc.). If you do, though, Capistrano will have to resolve those pseudo-revision identifiers every time, which can slow things down a little.
View
113 recipes/cached_externals.rb
@@ -38,6 +38,91 @@
end
end
+def in_local_stage?
+ exists?(:stage) && stage == :local
+end
+
+set(:shared_externals_dir) do
+ if in_local_stage?
+ File.expand_path("../shared/externals")
+ else
+ File.join(shared_path, "externals")
+ end
+end
+
+set(:shared_gems_dir) do
+ if in_local_stage?
+ File.expand_path("../shared/gems")
+ else
+ File.join(shared_path, "gems")
+ end
+end
+
+def process_external(path, options)
+ puts "configuring #{path}"
+ shared_dir = File.join(shared_externals_dir, path)
+
+ if options[:type] == 'gem'
+ process_external_gem(path, shared_dir, options)
+ else
+ process_external_scm(path, shared_dir, options)
+ end
+end
+
+def process_external_gem(path, shared_dir, options)
+ name = options[:name] || File.basename(path)
+ base = File.dirname(path)
+
+ destination = File.join(shared_gems_dir, "gems/#{name}-#{options[:version]}")
+ install_command = fetch(:gem, "gem") + " install --quiet --ignore-dependencies --no-ri --no-rdoc --install-dir='#{shared_gems_dir}' '#{name}' -v '#{options[:version]}'"
+
+ if in_local_stage?
+ FileUtils.rm_rf(path)
+ FileUtils.mkdir_p(base)
+ if !File.exists?(destination)
+ FileUtils.mkdir_p(shared_gems_dir)
+ system(install_command) or raise "error installing #{name}:#{options[:version]} gem"
+ end
+ FileUtils.ln_s(destination, path)
+ else
+ commands = [
+ "mkdir -p #{shared_gems_dir} #{base}",
+ install_command,
+ "if [ ! -d #{destination} ]; then (#{install_command}) || (rm -rf #{destination} && false); fi",
+ "ln -nsf #{destination} #{latest_release}/#{path}"
+ ]
+
+ run(command.join(" && "))
+ end
+end
+
+def process_external_scm(path, shared_dir, options)
+ scm = Capistrano::Deploy::SCM.new(options[:type], options)
+ revision =
+ begin
+ scm.query_revision(options[:revision]) { |cmd| `#{cmd}` }
+ rescue => scm_error
+ $stderr.puts scm_error
+ next
+ end
+
+ destination = File.join(shared_dir, revision)
+
+ if in_local_stage?
+ FileUtils.rm_rf(path)
+ FileUtils.mkdir_p(shared_dir)
+ if !File.exists?(destination)
+ unless system(scm.checkout(revision, destination))
+ FileUtils.rm_rf(destination) if File.exists?(destination)
+ raise "Error checking out #{revision} to #{destination}"
+ end
+ end
+ FileUtils.ln_s(destination, path)
+ else
+ run "rm -rf #{latest_release}/#{path} && mkdir -p #{shared_dir} && if [ ! -d #{destination} ]; then (#{scm.checkout(revision, destination)}) || rm -rf #{destination}; fi && ln -nsf #{destination} #{latest_release}/#{path}"
+ end
+end
+
desc "Indicate that externals should be applied locally. See externals:setup."
task :local do
set :stage, :local
@@ -63,33 +148,7 @@
require 'capistrano/recipes/deploy/scm'
external_modules.each do |path, options|
- puts "configuring #{path}"
- scm = Capistrano::Deploy::SCM.new(options[:type], options)
- revision =
- begin
- scm.query_revision(options[:revision]) { |cmd| `#{cmd}` }
- rescue => scm_error
- $stderr.puts scm_error
- next
- end
-
- if exists?(:stage) && stage == :local
- FileUtils.rm_rf(path)
- shared = File.expand_path(File.join("../shared/externals", path))
- FileUtils.mkdir_p(shared)
- destination = File.join(shared, revision)
- if !File.exists?(destination)
- unless system(scm.checkout(revision, destination))
- FileUtils.rm_rf(destination) if File.exists?(destination)
- raise "Error checking out #{revision} to #{destination}"
- end
- end
- FileUtils.ln_s(destination, path)
- else
- shared = File.join(shared_path, "externals", path)
- destination = File.join(shared, revision)
- run "rm -rf #{latest_release}/#{path} && mkdir -p #{shared} && if [ ! -d #{destination} ]; then (#{scm.checkout(revision, destination)}) || rm -rf #{destination}; fi && ln -nsf #{destination} #{latest_release}/#{path}"
- end
+ process_external(path, options)
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.