Class: Capistrano::Deploy::Strategy::CopySubdir

Inherits:
Copy
  • Object
show all
Defined in:
lib/capistrano/recipes/deploy/strategy/copy_subdir.rb

Constant Summary collapse

VERSION =
"0.0.1"

Instance Method Summary collapse

Instance Method Details

#deploy!Object

Obtains a copy of the source code locally (via the #command method), compresses it to a single file, copies that file to all target servers, and uncompresses it on each of them into the deployment directory.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/capistrano/recipes/deploy/strategy/copy_subdir.rb', line 12

def deploy!
  if copy_cache
    if File.exists?(copy_cache)
      logger.debug "refreshing local cache to revision #{revision} at #{copy_cache}"
      system(source.sync(revision, copy_cache))
    else
      logger.debug "preparing local cache at #{copy_cache}"
      system(source.checkout(revision, copy_cache))
    end

    # Check the return code of last system command and rollback if not 0
    unless $? == 0
      raise Capistrano::Error, "shell command failed with return code #{$?}"
    end

    FileUtils.mkdir_p(destination)

    logger.debug "copying cache to deployment staging area #{destination}"
    Dir.chdir(copy_cache) do
      queue = Dir.glob("*", File::FNM_DOTMATCH)
      while queue.any?
        item = queue.shift
        name = File.basename(item)

        next if name == "." || name == ".."
        next if copy_exclude.any? { |pattern| File.fnmatch(pattern, item) }

        if File.symlink?(item)
          FileUtils.ln_s(File.readlink(item), File.join(destination, item))
        elsif File.directory?(item)
          queue += Dir.glob("#{item}/*", File::FNM_DOTMATCH)
          FileUtils.mkdir(File.join(destination, item))
        else
          FileUtils.ln(item, File.join(destination, item))
        end
      end
    end
  else
    logger.debug "getting (via #{copy_strategy}) revision #{revision} to #{destination}"
    system(command)

    if copy_exclude.any?
      logger.debug "processing exclusions..."
      if copy_exclude.any?
        copy_exclude.each do |pattern|
          delete_list = Dir.glob(File.join(destination, pattern), File::FNM_DOTMATCH)
          # avoid the /.. trap that deletes the parent directories
          delete_list.delete_if { |dir| dir =~ /\/\.\.$/ }
          FileUtils.rm_rf(delete_list.compact)
        end
      end
    end
  end

  # merge stuffs under specific dirs
  if configuration[:merge_dirs]
    configuration[:merge_dirs].each do |dir, dest|
      from = Pathname.new(destination) + dir
      to = Pathname.new(destination) + dest
      logger.trace "#{from} > #{to}"
      FileUtils.mkdir_p(to)
      FileUtils.cp_r(Dir.glob(from), to)
    end
  end

  # for a rails application in sub directory
  #   set :deploy_subdir, "rails"
  if configuration[:deploy_subdir]
    subdir = configuration[:deploy_subdir]
    logger.trace "deploy subdir #{destination}/#{subdir}"
    Dir.mktmpdir do |dir|
      FileUtils.move("#{destination}/#{subdir}", dir)
      FileUtils.rm_rf destination rescue nil
      FileUtils.move("#{dir}/#{subdir}", "#{destination}")
    end
  end

  File.open(File.join(destination, "REVISION"), "w") { |f| f.puts(revision) }

  logger.trace "compressing #{destination} to #{filename}"
  Dir.chdir(copy_dir) { system(compress(File.basename(destination), File.basename(filename)).join(" ")) }

  distribute!
ensure
  puts $! if $!
  FileUtils.rm filename rescue nil
  FileUtils.rm_rf destination rescue nil
  FileUtils.rm_rf copy_subdir rescue nil
end