capistrano-file-transfer-ext 0.0.1 → 0.0.2
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.
@@ -7,36 +7,121 @@ module Capistrano
|
|
7
7
|
class Configuration
|
8
8
|
module Actions
|
9
9
|
module FileTransferExt
|
10
|
+
DIGEST_FILTER_CMD = %{awk '{for(n=1;n<=NF;n++){if(match($n,"^[0-9a-z]{16,}$")){print($n);break}}}'}
|
11
|
+
|
10
12
|
def safe_put(data, path, options={})
|
11
13
|
opts = options.dup
|
12
14
|
safe_upload(StringIO.new(data), path, opts)
|
13
15
|
end
|
14
16
|
|
17
|
+
# upload file from local to remote.
|
18
|
+
# this method uses temporary file to avoid incomplete transmission of files.
|
19
|
+
#
|
20
|
+
# The +options+ hash may include any of the following keys:
|
21
|
+
#
|
22
|
+
# * :transfer - use transfer_if_modified if :if_modified is set
|
23
|
+
# * :place - use place_if_modified if :if_modified is set
|
24
|
+
# * :run_method - the default is :run.
|
15
25
|
def safe_upload(from, to, options={}, &block)
|
16
|
-
|
17
|
-
|
18
|
-
|
26
|
+
transfer_method = options.delete(:transfer) == :if_modified ? :transfer_if_modified : :transfer
|
27
|
+
place_method = options.delete(:place) == :if_modified ? :place_if_modified : :place
|
28
|
+
run_method = ( options.delete(:run_method) || :run )
|
19
29
|
begin
|
20
30
|
tempname = File.join("/tmp", File.basename(to) + ".XXXXXXXXXX")
|
21
31
|
tempfile = capture("mktemp #{tempname.dump}").strip
|
22
32
|
run("rm -f #{tempfile.dump}", options)
|
23
|
-
|
24
|
-
|
25
|
-
case compare_method
|
26
|
-
when :diff
|
27
|
-
execute << "( diff -u #{to.dump} #{tempfile.dump} || mv -f #{tempfile.dump} #{to.dump} )"
|
28
|
-
else
|
29
|
-
execute << "( cmp #{to.dump} #{tempfile.dump} || mv -f #{tempfile.dump} #{to.dump} )"
|
30
|
-
end
|
31
|
-
if mode
|
32
|
-
mode = mode.is_a?(Numeric) ? mode.to_s(8) : mode.to_s
|
33
|
-
execute << "chmod #{mode} #{to}"
|
34
|
-
end
|
35
|
-
invoke_command(execute.join(" && "), options.merge(:via => via))
|
33
|
+
send(transfer_method, :up, from, tempfile, options, &block)
|
34
|
+
send(place_method, tempfile, to, options.merge(:via => run_method), &block)
|
36
35
|
ensure
|
37
36
|
run("rm -f #{tempfile.dump}", options) rescue nil
|
38
37
|
end
|
39
38
|
end
|
39
|
+
|
40
|
+
# transfer file (or IO like object) from local to remote, only if the file checksum is differ.
|
41
|
+
# do not care if the transfer has been completed or not.
|
42
|
+
#
|
43
|
+
# The +options+ hash may include any of the following keys:
|
44
|
+
#
|
45
|
+
# * :digest - digest algorithm. the default is "md5".
|
46
|
+
# * :digest_cmd - the digest command. the default is "#{digest}sum".
|
47
|
+
#
|
48
|
+
def transfer_if_modified(direction, from, to, options={}, &block)
|
49
|
+
digest_method = options.fetch(:digest, "md5")
|
50
|
+
digest_cmd = options.fetch(:digest_cmd, "#{digest_method.downcase}sum")
|
51
|
+
require "digest/#{digest_method.downcase}"
|
52
|
+
target = direction == :up ? from : to
|
53
|
+
remote_target = direction == :up ? to : from
|
54
|
+
if target.respond_to?(:read)
|
55
|
+
pos = target.pos
|
56
|
+
digest = Digest.const_get(digest_method.upcase).hexdigest(target.read)
|
57
|
+
target.pos = pos
|
58
|
+
else
|
59
|
+
begin
|
60
|
+
digest = Digest::const_get(digest_method.upcase).hexdigest(File.read(target))
|
61
|
+
rescue SystemCallError
|
62
|
+
digest = nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
if dry_run
|
66
|
+
logger.debug("transfering: #{[direction, from, to] * ', '}")
|
67
|
+
else
|
68
|
+
execute_on_servers(options) do |servers|
|
69
|
+
targets = servers.map { |server| sessions[server] }.reject { |session|
|
70
|
+
remote_digest = session.exec!("test -f #{remote_target.dump} && #{digest_cmd} #{remote_target.dump} | #{DIGEST_FILTER_CMD}")
|
71
|
+
result = !( digest.nil? or remote_digest.nil? ) && digest == remote_digest.strip
|
72
|
+
logger.info("#{session.xserver.host}: skip transfering since no changes: #{[direction, from, to] * ', '}") if result
|
73
|
+
result
|
74
|
+
}
|
75
|
+
Capistrano::Transfer.process(direction, from, to, targets, options.merge(:logger => logger), &block) unless targets.empty?
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# place a file on remote.
|
81
|
+
#
|
82
|
+
# The +options+ hash may include any of the following keys:
|
83
|
+
#
|
84
|
+
# * :mode - permission of the file.
|
85
|
+
# * :sudo - use sudo if set true. the default is false.
|
86
|
+
#
|
87
|
+
def place(from, to, options={}, &block)
|
88
|
+
mode = options.delete(:mode)
|
89
|
+
try_sudo = options.delete(:sudo) ? sudo : ""
|
90
|
+
execute = []
|
91
|
+
execute << "( test -d #{File.dirname(to).dump} || #{try_sudo} mkdir -p #{File.dirname(to).dump} )"
|
92
|
+
execute << "#{try_sudo} mv -f #{from.dump} #{to.dump}"
|
93
|
+
if mode
|
94
|
+
mode = mode.is_a?(Numeric) ? mode.to_s(8) : mode.to_s
|
95
|
+
execute << "#{try_sudo} chmod #{mode} #{to.dump}"
|
96
|
+
end
|
97
|
+
invoke_command(execute.join(" && "), options)
|
98
|
+
end
|
99
|
+
|
100
|
+
# place a file on remote, only if the destination is differ from source.
|
101
|
+
#
|
102
|
+
# The +options+ hash may include any of the following keys:
|
103
|
+
#
|
104
|
+
# * :mode - permission of the file.
|
105
|
+
# * :sudo - use sudo if set true. the default is false.
|
106
|
+
# * :digest - digest algorithm. the default is "md5".
|
107
|
+
# * :digest_cmd - the digest command. the default is "#{digest}sum".
|
108
|
+
#
|
109
|
+
def place_if_modified(from, to, options={}, &block)
|
110
|
+
mode = options.delete(:mode)
|
111
|
+
try_sudo = options.delete(:sudo) ? sudo : ""
|
112
|
+
digest_method = options.fetch(:digest, "md5")
|
113
|
+
digest_cmd = options.fetch(:digest_cmd, "#{digest_method.downcase}sum")
|
114
|
+
execute = []
|
115
|
+
execute << %{( test -d #{File.dirname(to).dump} || #{try_sudo} mkdir -p #{File.dirname(to).dump} )}
|
116
|
+
execute << %{from=$(#{digest_cmd} #{from.dump} | #{DIGEST_FILTER_CMD})}
|
117
|
+
execute << %{to=$(#{digest_cmd} #{to.dump} | #{DIGEST_FILTER_CMD})}
|
118
|
+
execute << %{( test "x${from}" = "x${to}" || ( echo #{from.dump} '->' #{to.dump}; #{try_sudo} mv -f #{from.dump} #{to.dump} ) )}
|
119
|
+
if mode
|
120
|
+
mode = mode.is_a?(Numeric) ? mode.to_s(8) : mode.to_s
|
121
|
+
execute << "#{try_sudo} chmod #{mode} #{to.dump}"
|
122
|
+
end
|
123
|
+
invoke_command(execute.join(" && "), options)
|
124
|
+
end
|
40
125
|
end
|
41
126
|
end
|
42
127
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-file-transfer-ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: capistrano
|