rbrsync 0.0.4 → 0.0.5

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.
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