rbrsync 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in rbrsync.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'rspec'
8
+ end
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbrsync (1.0.0)
5
- open4 (= 1.3.0)
4
+ rbrsync (0.0.4)
5
+ posix-spawn (~> 0.3.6)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  diff-lcs (1.2.2)
11
- open4 (1.3.0)
11
+ posix-spawn (0.3.6)
12
12
  rspec (2.13.0)
13
13
  rspec-core (~> 2.13.0)
14
14
  rspec-expectations (~> 2.13.0)
@@ -1,4 +1,4 @@
1
- require 'open4'
1
+ require 'posix-spawn'
2
2
 
3
3
  module RbRsync
4
4
  class RbRsync
@@ -9,7 +9,16 @@ module RbRsync
9
9
 
10
10
  self.from = from
11
11
  self.to = to
12
- self.rsync = "rsync"
12
+ end
13
+
14
+ class << self
15
+ def rsync_binary
16
+ @rsync_binary ||=
17
+ ENV['PATH'].split(':').
18
+ map { |p| File.join(p, 'rsync') }.
19
+ find { |p| File.exist?(p) }
20
+ end
21
+ attr_writer :rsync_binary
13
22
  end
14
23
 
15
24
  =begin
@@ -215,7 +224,6 @@ module RbRsync
215
224
  end
216
225
  end
217
226
 
218
- attr_accessor :rsync # the path to rsync
219
227
  attr_accessor :from_host, :from_user, :from_path
220
228
  attr_accessor :to_host, :to_user, :to_path
221
229
 
@@ -233,20 +241,13 @@ module RbRsync
233
241
  Negator.new self
234
242
  end
235
243
 
236
- # returns the rsync command that would be executed
237
- def command
238
- build_command.join ' '
239
- end
240
-
241
244
  # perform the sync
242
245
  def go!
243
246
  raise ArgumentError.new("a source and destination must be specified") if to.nil? || from.nil?
244
247
 
245
- status = Open4.popen4(command) do |pid, stdin, stdout, stderr|
246
- puts stderr.read if stderr
247
- end
248
-
248
+ POSIX::Spawn::Child.new(*build_command)
249
249
  end
250
+ alias_method :run!, :go!
250
251
 
251
252
  def self.boolean_methods
252
253
  @@boolean_methods
@@ -254,25 +255,49 @@ module RbRsync
254
255
 
255
256
  protected
256
257
  def build_command
257
- cmd = ['rsync']
258
+ argv = []
259
+ argv << RbRsync.rsync_binary
260
+
261
+ argv.concat(options_to_argv(@options))
258
262
 
259
- @options.each_pair do |flag, value|
260
- next if value.nil?
263
+ argv << from
264
+ argv << to
261
265
 
262
- if value.is_a? Array
263
- value.each do |v|
264
- cmd << "--#{flag}='#{v}'"
266
+ argv
267
+ end
268
+
269
+ # Transform a ruby-style options hash to command-line arguments sutiable for
270
+ # use with Kernel::exec. No shell escaping is performed.
271
+ #
272
+ # Returns an Array of String option arguments.
273
+ def options_to_argv(options)
274
+ argv = []
275
+ options.each do |key, val|
276
+ if key.to_s.size == 1
277
+ if val == true
278
+ argv << "-#{key}"
279
+ elsif val == false
280
+ # ignore
281
+ else
282
+ [val].flatten.each do |val|
283
+ argv << "-#{key}"
284
+ argv << "'#{shell_escape(val)}'"
285
+ end
265
286
  end
266
287
  else
267
- cmd << "--#{flag}"
288
+ if val == true
289
+ argv << "--#{key.to_s.tr('_', '-')}"
290
+ elsif val == false
291
+ # ignore
292
+ else
293
+ [val].flatten.each do |val|
294
+ argv << "--#{key.to_s.tr('_', '-')}='#{shell_escape(val)}'"
295
+ end
296
+
297
+ end
268
298
  end
269
299
  end
270
-
271
-
272
- cmd << from
273
- cmd << to
274
-
275
- cmd
300
+ argv
276
301
  end
277
302
 
278
303
  def build_path user, host, path
@@ -284,5 +309,9 @@ module RbRsync
284
309
  nil
285
310
  end
286
311
  end
312
+
313
+ def shell_escape(str)
314
+ str.to_s.gsub("'", "'\\\\''")
315
+ end
287
316
  end
288
317
  end
@@ -1,3 +1,3 @@
1
1
  module RbRsync
2
- VERSION = '0.0.4'
2
+ VERSION = '0.0.5'
3
3
  end
data/rbrsync.gemspec CHANGED
@@ -17,5 +17,5 @@ Gem::Specification.new do |s|
17
17
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
18
18
  s.require_paths = ["lib"]
19
19
 
20
- s.add_dependency 'open4', ['1.3.0']
20
+ s.add_dependency "posix-spawn", "~> 0.3.6"
21
21
  end
@@ -0,0 +1 @@
1
+ Some File
Binary file
@@ -0,0 +1,8 @@
1
+ An alpaca (Vicugna pacos) is a domesticated species of South American camelid. It resembles a small llama in appearance.
2
+ Alpacas are kept in herds that graze on the level heights of the Andes of southern Peru, northern Bolivia, Ecuador,
3
+ and northern Chile at an altitude of 3,500 m (11,500 ft) to 5,000 m (16,000 ft) above sea level, throughout the year.
4
+ Alpacas are considerably smaller than llamas, and unlike llamas, they were not bred to be beasts of burden, but were
5
+ bred specifically for their fiber. Alpaca fiber is used for making knitted and woven items, similar to wool. These
6
+ items include blankets, sweaters, hats, gloves, scarves, a wide variety of textiles and ponchos in South America,
7
+ and sweaters, socks, coats and bedding in other parts of the world. The fiber comes in more than 52 natural colors
8
+ as classified in Peru, 12 as classified in Australia and 16 as classified in the United States.
data/spec/rbrsync_spec.rb CHANGED
@@ -2,10 +2,27 @@ require 'spec_helper'
2
2
  require 'rbrsync'
3
3
 
4
4
  describe RbRsync do
5
+
6
+ before do
7
+ @fixtures = File.expand_path(File.join(File.dirname(__FILE__), "fixtures"))
8
+ end
9
+
5
10
  before :each do
6
11
  @rsync = RbRsync::RbRsync.new
7
12
  end
8
13
 
14
+ it "should find path to rsync binary" do
15
+ RbRsync::RbRsync.rsync_binary.should == `which rsync`.strip
16
+ end
17
+
18
+ it "should be able to set the path rsync binary" do
19
+ rsync_binary = RbRsync::RbRsync.rsync_binary
20
+ RbRsync::RbRsync.rsync_binary = '/test/git'
21
+ RbRsync::RbRsync.rsync_binary.should == '/test/git'
22
+ RbRsync::RbRsync.rsync_binary = rsync_binary
23
+ RbRsync::RbRsync.rsync_binary.should == rsync_binary
24
+ end
25
+
9
26
  it "should not have the archive flag set when archive! is not called" do
10
27
  @rsync.archive.should be_nil
11
28
  end
@@ -52,7 +69,7 @@ describe RbRsync do
52
69
  @rsync.archive.should be_true
53
70
  @rsync.fuzzy.should be_true
54
71
  end
55
-
72
+
56
73
  it "should allow underscores as dashes" do
57
74
  @rsync.human_readable!
58
75
  @rsync.human_readable.should be_true
@@ -127,57 +144,64 @@ describe RbRsync do
127
144
  end
128
145
 
129
146
  describe "command method" do
130
- def command_should_have_only command, from, to, *flags
147
+ def command_should_have_only from, to, *flags
148
+ argv = @rsync.send(:build_command)
149
+
131
150
  flags.each do |flag|
132
- command.should include flag
151
+ argv.should include flag
133
152
  end
134
153
 
135
- command.should =~ /^rsync/
136
- command.should =~ %r{#{from} #{to}$}
137
-
138
- command.gsub!(/^rsync/, '')
139
- command.gsub!(%r{#{from} #{to}$}, '')
154
+ argv.shift.should eq(RbRsync::RbRsync.rsync_binary)
155
+ argv.pop.should eq(to)
156
+ argv.pop.should eq(from)
140
157
 
141
- flags.each do |flag|
142
- command.sub! flag, ''
158
+ argv = argv.drop_while do |a|
159
+ flags.include?(a)
143
160
  end
144
161
 
145
- # with all the flags, the rsync command and the source and destination values stripped, there shouldn't be anything else
146
- command.strip.should == ""
162
+ # with all the flags, the rsync command and the source and destination values dropped, there shouldn't be anything else
163
+ argv.size.should eq(0)
147
164
  end
148
-
165
+
149
166
  it "should set the --archive flag when archive! is used" do
150
167
  @rsync.archive!
151
168
  @rsync.from = "/home/me/"
152
169
  @rsync.to = "user@host.com:/home/user"
153
-
154
- @rsync.command.should == "rsync --archive /home/me/ user@host.com:/home/user"
170
+
171
+ command_should_have_only "/home/me/", "user@host.com:/home/user", "--archive"
155
172
  end
156
-
173
+
157
174
  it "should set the --human-readable flag when human_readable! is used" do
158
175
  @rsync.human_readable!
159
176
  @rsync.from = "/home/me/"
160
177
  @rsync.to = "user@host.com:/home/user"
161
-
162
- @rsync.command.should == "rsync --human-readable /home/me/ user@host.com:/home/user"
178
+
179
+ command_should_have_only "/home/me/", "user@host.com:/home/user", "--human-readable"
163
180
  end
164
-
181
+
165
182
  it "should set the --archive and --exclude flags when archive! and exclude= are used" do
166
183
  @rsync.archive!
167
184
  @rsync.exclude = "*~"
168
185
  @rsync.from = "/home/me/"
169
186
  @rsync.to = "user@host.com:/home/user"
170
187
 
171
- command_should_have_only @rsync.command, "/home/me/", "user@host.com:/home/user", "--exclude='*~'", "--archive"
188
+ command_should_have_only "/home/me/", "user@host.com:/home/user", "--exclude='*~'", "--archive"
172
189
  end
173
190
  it "should set --exclude twice when exclude= is called with an array" do
174
191
  @rsync.exclude = ['*~', '/*']
175
192
  @rsync.from = "/home/me/"
176
193
  @rsync.to = "user@host.com:/home/user"
177
194
 
178
- command_should_have_only @rsync.command, "/home/me/", "user@host.com:/home/user", "--exclude='*~'", "--exclude='/*'"
195
+ command_should_have_only "/home/me/", "user@host.com:/home/user", "--exclude='*~'", "--exclude='/*'"
196
+ end
197
+
198
+ it "should correctly escape argument values" do
199
+ @rsync.log_file = 'rsync.log'
200
+ @rsync.log_file_format = "'\\'%t '%f' with %b ''"
201
+ @rsync.from = "/home"
202
+ @rsync.to = "/home/user"
203
+ command_should_have_only "/home", "/home/user", "--log-file='rsync.log'", %q[--log-file-format=''\''\'\''%t '\''%f'\'' with %b '\'''\''']
179
204
  end
180
-
181
205
  end
182
206
 
183
207
  describe "constructor" do
@@ -204,4 +228,28 @@ describe RbRsync do
204
228
  @rsync.send(:build_command).should include "--archive"
205
229
  end
206
230
  end
231
+
232
+ describe 'shell_escape' do
233
+ it "should escape ' and ;" do
234
+ @rsync.send(:shell_escape, "'some \\'quoted 'string 'with a ''").should == %q['\''some \'\''quoted '\''string '\''with a '\'''\'']
235
+ end
236
+ end
237
+
238
+ describe "go!" do
239
+ it "should match rsync output" do
240
+ @rsync.from = File.join(@fixtures, "from")
241
+ @rsync.to = File.join(@fixtures, "to")
242
+ @rsync.recursive!
243
+ @rsync.verbose!
244
+ process = @rsync.go!
245
+
246
+ process.status.success?.should be_true
247
+ process.out.should match(/total size is .* speedup is .*/)
248
+ end
249
+ end
250
+
251
+ after do
252
+ # Cleanup
253
+ system "rm -rf #{File.join(@fixtures, 'to', '*')}"
254
+ end
207
255
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbrsync
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,27 +13,26 @@ cert_chain: []
13
13
  date: 2013-04-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: open4
16
+ name: posix-spawn
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
- - - '='
20
+ - - ~>
21
21
  - !ruby/object:Gem::Version
22
- version: 1.3.0
22
+ version: 0.3.6
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  none: false
27
27
  requirements:
28
- - - '='
28
+ - - ~>
29
29
  - !ruby/object:Gem::Version
30
- version: 1.3.0
30
+ version: 0.3.6
31
31
  description: A thin Ruby wrapper around rsync
32
32
  email:
33
33
  - caleb.land@gmail.com
34
34
  - koen@fetch.nl
35
- executables:
36
- - rbrsync
35
+ executables: []
37
36
  extensions: []
38
37
  extra_rdoc_files: []
39
38
  files:
@@ -47,16 +46,18 @@ files:
47
46
  - README.md
48
47
  - README.rdoc
49
48
  - Rakefile
50
- - bin/rbrsync
51
49
  - lib/rbrsync.rb
52
50
  - lib/rbrsync/negator.rb
53
51
  - lib/rbrsync/option.rb
54
52
  - lib/rbrsync/rbrsync.rb
55
53
  - lib/rbrsync/version.rb
56
54
  - rbrsync.gemspec
55
+ - spec/fixtures/from/file-1.txt
56
+ - spec/fixtures/from/main/alpaca.jpg
57
+ - spec/fixtures/from/main/file-2.txt
58
+ - spec/fixtures/to/.gitkeep
57
59
  - spec/rbrsync_spec.rb
58
60
  - spec/spec_helper.rb
59
- - test/test_rbsync.rb
60
61
  homepage: http://www.github.com/koenpunt/rbrsync
61
62
  licenses: []
62
63
  post_install_message:
@@ -82,6 +83,9 @@ signing_key:
82
83
  specification_version: 3
83
84
  summary: A thin Ruby wrapper around rsync
84
85
  test_files:
86
+ - spec/fixtures/from/file-1.txt
87
+ - spec/fixtures/from/main/alpaca.jpg
88
+ - spec/fixtures/from/main/file-2.txt
89
+ - spec/fixtures/to/.gitkeep
85
90
  - spec/rbrsync_spec.rb
86
91
  - spec/spec_helper.rb
87
- - test/test_rbsync.rb
data/bin/rbrsync DELETED
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require File.expand_path(
4
- File.join(File.dirname(__FILE__), %w[.. lib rbsync]))
5
-
6
- # Put your code here
File without changes