rbrsync 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.
- data/.bnsignore +16 -0
- data/.gitignore +17 -0
- data/.tm_properties +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +26 -0
- data/History.txt +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/README.rdoc +89 -0
- data/Rakefile +1 -0
- data/bin/rbrsync +6 -0
- data/lib/rbrsync/negator.rb +20 -0
- data/lib/rbrsync/option.rb +19 -0
- data/lib/rbrsync/rbrsync.rb +307 -0
- data/lib/rbrsync/version.rb +3 -0
- data/lib/rbrsync.rb +8 -0
- data/rbrsync.gemspec +21 -0
- data/spec/rbrsync_spec.rb +207 -0
- data/spec/spec_helper.rb +17 -0
- data/test/test_rbsync.rb +0 -0
- metadata +87 -0
data/.bnsignore
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# The list of files that should be ignored by Mr Bones.
|
2
|
+
# Lines that start with '#' are comments.
|
3
|
+
#
|
4
|
+
# A .gitignore file can be used instead by setting it as the ignore
|
5
|
+
# file in your Rakefile:
|
6
|
+
#
|
7
|
+
# PROJ.ignore_file = '.gitignore'
|
8
|
+
#
|
9
|
+
# For a project with a C extension, the following would be a good set of
|
10
|
+
# exclude patterns (uncomment them if you want to use them):
|
11
|
+
# *.[oa]
|
12
|
+
# *~
|
13
|
+
announcement.txt
|
14
|
+
coverage
|
15
|
+
doc
|
16
|
+
pkg
|
data/.gitignore
ADDED
data/.tm_properties
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
projectDirectory = "$CWD"
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rbrsync (1.0.0)
|
5
|
+
open4 (= 1.3.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
diff-lcs (1.2.2)
|
11
|
+
open4 (1.3.0)
|
12
|
+
rspec (2.13.0)
|
13
|
+
rspec-core (~> 2.13.0)
|
14
|
+
rspec-expectations (~> 2.13.0)
|
15
|
+
rspec-mocks (~> 2.13.0)
|
16
|
+
rspec-core (2.13.1)
|
17
|
+
rspec-expectations (2.13.0)
|
18
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
19
|
+
rspec-mocks (2.13.1)
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
rbrsync!
|
26
|
+
rspec
|
data/History.txt
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Koen Punt
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# RbRsync
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'rbrsync'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install rbrsync
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/README.rdoc
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
rbsync
|
2
|
+
by Caleb Land
|
3
|
+
http://www.github.com/caleb/rbsync
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
RBSync is a thin Ruby wrapper around rsync. It removes the string building
|
8
|
+
from calling rsync from ruby.
|
9
|
+
|
10
|
+
== FEATURES/PROBLEMS:
|
11
|
+
|
12
|
+
* RBSync is a thin wrapper so it exposes as much of rsync's power as possible
|
13
|
+
* RBSync requires that rsync be installed
|
14
|
+
|
15
|
+
== SYNOPSIS:
|
16
|
+
|
17
|
+
RBSync has a convenience class which makes it easy to sync with rsync's archive (-a) flag:
|
18
|
+
|
19
|
+
import 'rubygems'
|
20
|
+
import 'rbsync'
|
21
|
+
|
22
|
+
# Builds a usable rsync command using the -a (archive) flag to rsync
|
23
|
+
rsync = RBSync::RBSync.new '/mysite/', 'me@myhost.com:/var/www/mysite'
|
24
|
+
rsync.archive!
|
25
|
+
rsync.go!
|
26
|
+
|
27
|
+
If you want more control, you could specify each flag separately. This command
|
28
|
+
is equivalent to the one above:
|
29
|
+
|
30
|
+
rsync = RBSync::RBsync.new '/mysite/', 'me@myhost.com:/var/www/mysite'
|
31
|
+
# turns on rsync's delete flag (--delete)
|
32
|
+
rsync.delete!
|
33
|
+
rsync.recursive!
|
34
|
+
rsync.links!
|
35
|
+
rsync.perms!
|
36
|
+
rsync.times!
|
37
|
+
rsync.group!
|
38
|
+
rsync.owner!
|
39
|
+
rsync.devices!
|
40
|
+
rsync.specials!
|
41
|
+
rsync.go!
|
42
|
+
|
43
|
+
You can even use the archive flag and turn off those flags which you don't want:
|
44
|
+
rsync = RBSync::RBsync.new '/mysite/', 'me@myhost.com:/var/www/mysite'
|
45
|
+
rsync.archive!
|
46
|
+
|
47
|
+
# turn off the times (--times) flag
|
48
|
+
~ rsync.times!
|
49
|
+
|
50
|
+
# turn off the devices (--devices) flag
|
51
|
+
rsync.devices = false
|
52
|
+
|
53
|
+
# turn off the recursive (--recursive) flag
|
54
|
+
rsync.no.recursive!
|
55
|
+
|
56
|
+
rsync.go!
|
57
|
+
|
58
|
+
== REQUIREMENTS:
|
59
|
+
|
60
|
+
* Ruby >= 1.8.7
|
61
|
+
|
62
|
+
== INSTALL:
|
63
|
+
|
64
|
+
* sudo gem install rbsync
|
65
|
+
|
66
|
+
== LICENSE:
|
67
|
+
|
68
|
+
(The MIT License)
|
69
|
+
|
70
|
+
Copyright (c) 2009
|
71
|
+
|
72
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
73
|
+
a copy of this software and associated documentation files (the
|
74
|
+
'Software'), to deal in the Software without restriction, including
|
75
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
76
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
77
|
+
permit persons to whom the Software is furnished to do so, subject to
|
78
|
+
the following conditions:
|
79
|
+
|
80
|
+
The above copyright notice and this permission notice shall be
|
81
|
+
included in all copies or substantial portions of the Software.
|
82
|
+
|
83
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
84
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
85
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
86
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
87
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
88
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
89
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/rbrsync
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
module RbRsync
|
3
|
+
class Negator
|
4
|
+
|
5
|
+
def initialize rbsync
|
6
|
+
@rbsync = rbsync
|
7
|
+
|
8
|
+
RbRsync.boolean_methods.each do |m|
|
9
|
+
|
10
|
+
(class << self; self; end).class_eval <<-RUBY
|
11
|
+
def #{m}
|
12
|
+
@rbsync.#{m.gsub(/!$/, '')} = false
|
13
|
+
end
|
14
|
+
RUBY
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
module RbRsync
|
4
|
+
class Option < SimpleDelegator
|
5
|
+
attr_reader :rbsync
|
6
|
+
attr_reader :name
|
7
|
+
|
8
|
+
def initialize rbsync, name
|
9
|
+
super(rbsync)
|
10
|
+
|
11
|
+
@rbsync = rbsync
|
12
|
+
@name = name
|
13
|
+
end
|
14
|
+
|
15
|
+
def ~
|
16
|
+
self.rbsync.send("#{name}=", false)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,307 @@
|
|
1
|
+
require 'open4'
|
2
|
+
|
3
|
+
module RbRsync
|
4
|
+
class RbRsync
|
5
|
+
@@boolean_methods = []
|
6
|
+
|
7
|
+
def initialize from=nil, to=nil
|
8
|
+
@options = {}
|
9
|
+
|
10
|
+
self.from = from
|
11
|
+
self.to = to
|
12
|
+
self.rsync = "rsync"
|
13
|
+
end
|
14
|
+
|
15
|
+
=begin
|
16
|
+
0 Success
|
17
|
+
|
18
|
+
1 Syntax or usage error
|
19
|
+
|
20
|
+
2 Protocol incompatibility
|
21
|
+
|
22
|
+
3 Errors selecting input/output files, dirs
|
23
|
+
|
24
|
+
4 Requested action not supported: an attempt was made to manipu-
|
25
|
+
late 64-bit files on a platform that cannot support them; or an
|
26
|
+
option was specified that is supported by the client and not by
|
27
|
+
the server.
|
28
|
+
|
29
|
+
5 Error starting client-server protocol
|
30
|
+
|
31
|
+
6 Daemon unable to append to log-file
|
32
|
+
|
33
|
+
10 Error in socket I/O
|
34
|
+
|
35
|
+
11 Error in file I/O
|
36
|
+
|
37
|
+
12 Error in rsync protocol data stream
|
38
|
+
|
39
|
+
13 Errors with program diagnostics
|
40
|
+
|
41
|
+
14 Error in IPC code
|
42
|
+
|
43
|
+
20 Received SIGUSR1 or SIGINT
|
44
|
+
|
45
|
+
21 Some error returned by waitpid()
|
46
|
+
|
47
|
+
22 Error allocating core memory buffers
|
48
|
+
|
49
|
+
23 Partial transfer due to error
|
50
|
+
|
51
|
+
24 Partial transfer due to vanished source files
|
52
|
+
|
53
|
+
25 The --max-delete limit stopped deletions
|
54
|
+
|
55
|
+
30 Timeout in data send/receive
|
56
|
+
|
57
|
+
35 Timeout waiting for daemon connection
|
58
|
+
=end
|
59
|
+
|
60
|
+
# define the flags
|
61
|
+
(%w{
|
62
|
+
--verbose
|
63
|
+
--quiet
|
64
|
+
--no-motd
|
65
|
+
--checksum
|
66
|
+
--archive
|
67
|
+
--no-OPTION
|
68
|
+
--recursive
|
69
|
+
--relative
|
70
|
+
--no-implied-dirs
|
71
|
+
--backup
|
72
|
+
--backup-dir=DIR
|
73
|
+
--suffix=SUFFIX
|
74
|
+
--update
|
75
|
+
--inplace
|
76
|
+
--append
|
77
|
+
--append-verify
|
78
|
+
--dirs
|
79
|
+
--links
|
80
|
+
--copy-links
|
81
|
+
--copy-unsafe-links
|
82
|
+
--safe-links
|
83
|
+
--copy-dirlinks
|
84
|
+
--keep-dirlinks
|
85
|
+
--hard-links
|
86
|
+
--perms
|
87
|
+
--executability
|
88
|
+
--chmod=CHMOD
|
89
|
+
--acls
|
90
|
+
--xattrs
|
91
|
+
--owner
|
92
|
+
--group
|
93
|
+
--devices
|
94
|
+
--specials
|
95
|
+
|
96
|
+
--times
|
97
|
+
--omit-dir-times
|
98
|
+
--super
|
99
|
+
--fake-super
|
100
|
+
--sparse
|
101
|
+
--dry-run
|
102
|
+
--whole-file
|
103
|
+
--one-file-system
|
104
|
+
--block-size=SIZE
|
105
|
+
--rsh=COMMAND
|
106
|
+
--rsync-path=PROGRAM
|
107
|
+
--existing
|
108
|
+
--ignore-existing
|
109
|
+
--remove-source-files
|
110
|
+
--del
|
111
|
+
--delete
|
112
|
+
--delete-before
|
113
|
+
--delete-during
|
114
|
+
--delete-delay
|
115
|
+
--delete-after
|
116
|
+
--delete-excluded
|
117
|
+
--ignore-errors
|
118
|
+
--force
|
119
|
+
--max-delete=NUM
|
120
|
+
--max-size=SIZE
|
121
|
+
--min-size=SIZE
|
122
|
+
--partial
|
123
|
+
--partial-dir=DIR
|
124
|
+
--delay-updates
|
125
|
+
--prune-empty-dirs
|
126
|
+
--numeric-ids
|
127
|
+
--timeout=SECONDS
|
128
|
+
--contimeout=SECONDS
|
129
|
+
--ignore-times
|
130
|
+
--size-only
|
131
|
+
--modify-window=NUM
|
132
|
+
--temp-dir=DIR
|
133
|
+
--fuzzy
|
134
|
+
--compare-dest=DIR
|
135
|
+
--copy-dest=DIR
|
136
|
+
--link-dest=DIR
|
137
|
+
--compress
|
138
|
+
--compress-level=NUM
|
139
|
+
--skip-compress=LIST
|
140
|
+
--cvs-exclude
|
141
|
+
--filter=RULE
|
142
|
+
|
143
|
+
--exclude=PATTERN
|
144
|
+
--exclude-from=FILE
|
145
|
+
--include=PATTERN
|
146
|
+
--include-from=FILE
|
147
|
+
--files-from=FILE
|
148
|
+
--from0
|
149
|
+
--protect-args
|
150
|
+
--address=ADDRESS
|
151
|
+
--port=PORT
|
152
|
+
--sockopts=OPTIONS
|
153
|
+
--blocking-io
|
154
|
+
--stats
|
155
|
+
--8-bit-output
|
156
|
+
--human-readable
|
157
|
+
--progress
|
158
|
+
|
159
|
+
--itemize-changes
|
160
|
+
--out-format=FORMAT
|
161
|
+
--log-file=FILE
|
162
|
+
--log-file-format=FMT
|
163
|
+
--password-file=FILE
|
164
|
+
--list-only
|
165
|
+
--bwlimit=KBPS
|
166
|
+
--write-batch=FILE
|
167
|
+
--only-write-batch=FILE
|
168
|
+
--read-batch=FILE
|
169
|
+
--protocol=NUM
|
170
|
+
--iconv=CONVERT_SPEC
|
171
|
+
--checksum-seed=NUM
|
172
|
+
--ipv4
|
173
|
+
--ipv6
|
174
|
+
--version
|
175
|
+
--help
|
176
|
+
}).each do |flag|
|
177
|
+
flag.gsub!(/^--/, '')
|
178
|
+
flag = flag.split '='
|
179
|
+
|
180
|
+
raise "a flag should be non-empty and contain only one equals sign" unless [1, 2].include? flag.size
|
181
|
+
|
182
|
+
flag_name = flag[0]
|
183
|
+
name = flag_name.dup
|
184
|
+
name.gsub!(/-/, '_')
|
185
|
+
name.gsub!(/^8/, 'eight')
|
186
|
+
name.gsub!(/^(\d+)/, '_\1')
|
187
|
+
|
188
|
+
# define the read accessor
|
189
|
+
define_method name do
|
190
|
+
@options[flag_name]
|
191
|
+
end
|
192
|
+
|
193
|
+
# if the flag has two components, it contains an equals sign, and accepts a value
|
194
|
+
# else, it has only one and doesn't contain an equals sign, which makes it a boolean flag
|
195
|
+
if flag.size == 2
|
196
|
+
argument = flag[1]
|
197
|
+
|
198
|
+
define_method "#{name}=" do |value|
|
199
|
+
@options[flag_name] = [value].flatten
|
200
|
+
end
|
201
|
+
elsif flag.size == 1
|
202
|
+
alias_method "#{name}?".to_sym, name
|
203
|
+
@@boolean_methods << "#{name}!"
|
204
|
+
|
205
|
+
define_method "#{name}=" do |value|
|
206
|
+
raise ArgumentError, "value must be either true, false, or nil" unless [true, false, nil].include?(value)
|
207
|
+
@options[flag_name] = value
|
208
|
+
end
|
209
|
+
define_method "#{name}!" do
|
210
|
+
self.send "#{name}=", true
|
211
|
+
Option.new self, name
|
212
|
+
end
|
213
|
+
else
|
214
|
+
raise "a flag should contain only one equals sign"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
attr_accessor :rsync # the path to rsync
|
219
|
+
attr_accessor :from_host, :from_user, :from_path
|
220
|
+
attr_accessor :to_host, :to_user, :to_path
|
221
|
+
|
222
|
+
def from
|
223
|
+
@from || build_path(from_user, from_host, from_path)
|
224
|
+
end
|
225
|
+
attr_writer :from
|
226
|
+
|
227
|
+
def to
|
228
|
+
@to || build_path(to_user, to_host, to_path)
|
229
|
+
end
|
230
|
+
attr_writer :to
|
231
|
+
|
232
|
+
def no
|
233
|
+
Negator.new self
|
234
|
+
end
|
235
|
+
|
236
|
+
# returns the rysnc command that would be executed
|
237
|
+
def command
|
238
|
+
cmd = build_command
|
239
|
+
c = ""
|
240
|
+
c << "rsync"
|
241
|
+
@options.each_pair do |flag, value|
|
242
|
+
next if value.nil?
|
243
|
+
|
244
|
+
if value.is_a? Array
|
245
|
+
value.each do |v|
|
246
|
+
c << " --#{flag}='#{v}'"
|
247
|
+
end
|
248
|
+
else
|
249
|
+
c << " --#{flag}"
|
250
|
+
end
|
251
|
+
|
252
|
+
end
|
253
|
+
|
254
|
+
c << " #{from} #{to}"
|
255
|
+
|
256
|
+
c
|
257
|
+
end
|
258
|
+
|
259
|
+
# perform the sync
|
260
|
+
def go!
|
261
|
+
raise ArgumentError.new("a source and destination must be specified") if to.nil? || from.nil?
|
262
|
+
|
263
|
+
cmd = build_command
|
264
|
+
|
265
|
+
status = Open4.popen4(*cmd) do |pid, stdin, stdout, stderr|
|
266
|
+
end
|
267
|
+
|
268
|
+
puts status.exitstatus
|
269
|
+
end
|
270
|
+
|
271
|
+
def self.boolean_methods
|
272
|
+
@@boolean_methods
|
273
|
+
end
|
274
|
+
|
275
|
+
protected
|
276
|
+
def build_command
|
277
|
+
cmd = []
|
278
|
+
cmd << 'rsync'
|
279
|
+
|
280
|
+
@options.each_pair do |flag, value|
|
281
|
+
next if value.nil?
|
282
|
+
c = "--#{flag}"
|
283
|
+
|
284
|
+
if value.is_a? String
|
285
|
+
c << "=#{value}"
|
286
|
+
end
|
287
|
+
|
288
|
+
cmd << c
|
289
|
+
end
|
290
|
+
|
291
|
+
cmd << from
|
292
|
+
cmd << to
|
293
|
+
|
294
|
+
cmd
|
295
|
+
end
|
296
|
+
|
297
|
+
def build_path user, host, path
|
298
|
+
if ! user.nil? && ! host.nil? && ! path.nil?
|
299
|
+
"#{user}@#{host}:#{path}"
|
300
|
+
elsif user.nil? && host.nil? && ! path.nil?
|
301
|
+
path
|
302
|
+
else
|
303
|
+
nil
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
data/lib/rbrsync.rb
ADDED
data/rbrsync.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rbrsync/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "rbrsync"
|
8
|
+
s.version = RbRsync::VERSION
|
9
|
+
s.authors = ["Caleb Land", "Koen Punt"]
|
10
|
+
s.email = ["caleb.land@gmail.com", "koen@fetch.nl"]
|
11
|
+
s.description = %q{A thin Ruby wrapper around rsync}
|
12
|
+
s.summary = %q{A thin Ruby wrapper around rsync}
|
13
|
+
s.homepage = "http://www.github.com/koenpunt/rbrsync"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split($/)
|
16
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency 'open4', ['1.3.0']
|
21
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rbrsync'
|
3
|
+
|
4
|
+
describe RbRsync do
|
5
|
+
before :each do
|
6
|
+
@rsync = RbRsync::RbRsync.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should not have the archive flag set when archive! is not called" do
|
10
|
+
@rsync.archive.should be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should include the archive flag when archive! is called" do
|
14
|
+
@rsync.archive!
|
15
|
+
@rsync.archive.should be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should include the archive flag when archive is set to true with archive=" do
|
19
|
+
@rsync.archive = true
|
20
|
+
@rsync.archive.should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have the archive flag set to false when ~ is used on the option" do
|
24
|
+
~ @rsync.archive!
|
25
|
+
@rsync.archive.should be_false
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have the archive flag set to false when archive! is chained with no" do
|
29
|
+
@rsync.no.archive!
|
30
|
+
@rsync.archive.should be_false
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should raise an ArgumentError if a non boolean value (one that is not true, false, or nil) is assigned to a boolean flag" do
|
34
|
+
lambda {
|
35
|
+
@rsync.archive = "string"
|
36
|
+
}.should raise_error(ArgumentError)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should set the rsh flag when called with rsh=" do
|
40
|
+
@rsync.rsh = "/usr/bin/ssh"
|
41
|
+
@rsync.rsh.should include("/usr/bin/ssh")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should raise a NameError when a non boolean flag is used with rsync.no" do
|
45
|
+
lambda {
|
46
|
+
@rsync.no.rsh = "/usr/bin/ssh"
|
47
|
+
}.should raise_error(NameError)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should allow chaining of boolean flags" do
|
51
|
+
@rsync.archive!.fuzzy!
|
52
|
+
@rsync.archive.should be_true
|
53
|
+
@rsync.fuzzy.should be_true
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should allow underscores as dashes" do
|
57
|
+
@rsync.human_readable!
|
58
|
+
@rsync.human_readable.should be_true
|
59
|
+
end
|
60
|
+
|
61
|
+
#destination
|
62
|
+
it "should construct an rsync path when the individual destination properties are set" do
|
63
|
+
@rsync.to_user = "user"
|
64
|
+
@rsync.to_host = "host.com"
|
65
|
+
@rsync.to_path = "/home/user"
|
66
|
+
|
67
|
+
@rsync.to.should == "user@host.com:/home/user"
|
68
|
+
end
|
69
|
+
it "should have a nil destination if a user is set but not a host and vice versa for a destination" do
|
70
|
+
@rsync.to_user = "user"
|
71
|
+
@rsync.to_path = "/home/user"
|
72
|
+
@rsync.to.should be_nil
|
73
|
+
|
74
|
+
rsync2 = RbRsync::RbRsync.new
|
75
|
+
rsync2.to_host = "host.com"
|
76
|
+
rsync2.to_path = "/home/user"
|
77
|
+
rsync2.to.should be_nil
|
78
|
+
end
|
79
|
+
it "should have a nil destination if a destination path is not provided" do
|
80
|
+
@rsync.to_user = "user"
|
81
|
+
@rsync.to_host = "host.com"
|
82
|
+
@rsync.to.should be_nil
|
83
|
+
end
|
84
|
+
it "should prefer an explicitly set destination over the components" do
|
85
|
+
@rsync.to_user = "user"
|
86
|
+
@rsync.to_host = "host.com"
|
87
|
+
@rsync.to_path = "/home/user"
|
88
|
+
|
89
|
+
@rsync.to = "newuser@newhost.com:/home/newuser"
|
90
|
+
|
91
|
+
@rsync.to.should == "newuser@newhost.com:/home/newuser"
|
92
|
+
end
|
93
|
+
|
94
|
+
# source
|
95
|
+
it "should construct an rsync path when the individual source properties are set" do
|
96
|
+
@rsync.from_user = "user"
|
97
|
+
@rsync.from_host = "host.com"
|
98
|
+
@rsync.from_path = "/home/user"
|
99
|
+
|
100
|
+
@rsync.from.should == "user@host.com:/home/user"
|
101
|
+
end
|
102
|
+
it "should have a nil source if a user is set but not a host and vice versa for a source" do
|
103
|
+
@rsync.from_user = "user"
|
104
|
+
@rsync.from_path = "/home/user"
|
105
|
+
|
106
|
+
@rsync.from.should be_nil
|
107
|
+
|
108
|
+
rsync2 = RbRsync::RbRsync.new
|
109
|
+
rsync2.from_host = "host.com"
|
110
|
+
rsync2.from_path = "/home/user"
|
111
|
+
rsync2.from.should be_nil
|
112
|
+
end
|
113
|
+
it "should have a nil source if a source path is not provided" do
|
114
|
+
@rsync.from_user = "user"
|
115
|
+
@rsync.from_host = "host.com"
|
116
|
+
|
117
|
+
@rsync.from.should be_nil
|
118
|
+
end
|
119
|
+
it "should prefer an explicitly set source over the components" do
|
120
|
+
@rsync.from_user = "user"
|
121
|
+
@rsync.from_host = "host.com"
|
122
|
+
@rsync.from_path = "/home/user"
|
123
|
+
|
124
|
+
@rsync.from = "newuser@newhost.com:/home/newuser"
|
125
|
+
|
126
|
+
@rsync.from.should == "newuser@newhost.com:/home/newuser"
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "command method" do
|
130
|
+
def command_should_have_only command, from, to, *flags
|
131
|
+
flags.each do |flag|
|
132
|
+
command.should include flag
|
133
|
+
end
|
134
|
+
|
135
|
+
command.should =~ /^rsync/
|
136
|
+
command.should =~ %r{#{from} #{to}$}
|
137
|
+
|
138
|
+
command.gsub!(/^rsync/, '')
|
139
|
+
command.gsub!(%r{#{from} #{to}$}, '')
|
140
|
+
|
141
|
+
flags.each do |flag|
|
142
|
+
command.sub! flag, ''
|
143
|
+
end
|
144
|
+
|
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 == ""
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should set the --archive flag when archive! is used" do
|
150
|
+
@rsync.archive!
|
151
|
+
@rsync.from = "/home/me/"
|
152
|
+
@rsync.to = "user@host.com:/home/user"
|
153
|
+
|
154
|
+
@rsync.command.should == "rsync --archive /home/me/ user@host.com:/home/user"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should set the --human-readable flag when human_readable! is used" do
|
158
|
+
@rsync.human_readable!
|
159
|
+
@rsync.from = "/home/me/"
|
160
|
+
@rsync.to = "user@host.com:/home/user"
|
161
|
+
|
162
|
+
@rsync.command.should == "rsync --human-readable /home/me/ user@host.com:/home/user"
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should set the --archive and --exclude flags when archive! and exclude= are used" do
|
166
|
+
@rsync.archive!
|
167
|
+
@rsync.exclude = "*~"
|
168
|
+
@rsync.from = "/home/me/"
|
169
|
+
@rsync.to = "user@host.com:/home/user"
|
170
|
+
|
171
|
+
command_should_have_only @rsync.command, "/home/me/", "user@host.com:/home/user", "--exclude='*~'", "--archive"
|
172
|
+
end
|
173
|
+
it "should set --exclude twice when exclude= is called with an array" do
|
174
|
+
@rsync.exclude = ['*~', '/*']
|
175
|
+
@rsync.from = "/home/me/"
|
176
|
+
@rsync.to = "user@host.com:/home/user"
|
177
|
+
|
178
|
+
command_should_have_only @rsync.command, "/home/me/", "user@host.com:/home/user", "--exclude='*~'", "--exclude='/*'"
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
describe "constructor" do
|
184
|
+
it "should take source and destination parameters" do
|
185
|
+
@rsync = RbRsync::RbRsync.new '/home/user', 'user@host.com:/home/user'
|
186
|
+
@rsync.from.should == '/home/user'
|
187
|
+
@rsync.to.should == 'user@host.com:/home/user'
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should have no source or destination if the source and destination parameters are omitted from the constructor" do
|
191
|
+
@rsync = RbRsync::RbRsync.new
|
192
|
+
|
193
|
+
@rsync.from.should be_nil
|
194
|
+
@rsync.to.should be_nil
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe "build_command" do
|
199
|
+
it "should have the --archive flag when the archive! method is used" do
|
200
|
+
@rsync.archive!
|
201
|
+
@rsync.from = "-bwah /Users/caleb/Desktop/BBEdit_9.2_Demo.dmg"
|
202
|
+
@rsync.to = "/tmp"
|
203
|
+
|
204
|
+
@rsync.send(:build_command).should include "--archive"
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
|
12
|
+
# Run specs in random order to surface order dependencies. If you find an
|
13
|
+
# order dependency and want to debug it, you can fix the order by providing
|
14
|
+
# the seed, which is printed after each run.
|
15
|
+
# --seed 1234
|
16
|
+
config.order = 'random'
|
17
|
+
end
|
data/test/test_rbsync.rb
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rbrsync
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Caleb Land
|
9
|
+
- Koen Punt
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2013-04-09 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: open4
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - '='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.3.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - '='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 1.3.0
|
31
|
+
description: A thin Ruby wrapper around rsync
|
32
|
+
email:
|
33
|
+
- caleb.land@gmail.com
|
34
|
+
- koen@fetch.nl
|
35
|
+
executables:
|
36
|
+
- rbrsync
|
37
|
+
extensions: []
|
38
|
+
extra_rdoc_files: []
|
39
|
+
files:
|
40
|
+
- .bnsignore
|
41
|
+
- .gitignore
|
42
|
+
- .tm_properties
|
43
|
+
- Gemfile
|
44
|
+
- Gemfile.lock
|
45
|
+
- History.txt
|
46
|
+
- LICENSE.txt
|
47
|
+
- README.md
|
48
|
+
- README.rdoc
|
49
|
+
- Rakefile
|
50
|
+
- bin/rbrsync
|
51
|
+
- lib/rbrsync.rb
|
52
|
+
- lib/rbrsync/negator.rb
|
53
|
+
- lib/rbrsync/option.rb
|
54
|
+
- lib/rbrsync/rbrsync.rb
|
55
|
+
- lib/rbrsync/version.rb
|
56
|
+
- rbrsync.gemspec
|
57
|
+
- spec/rbrsync_spec.rb
|
58
|
+
- spec/spec_helper.rb
|
59
|
+
- test/test_rbsync.rb
|
60
|
+
homepage: http://www.github.com/koenpunt/rbrsync
|
61
|
+
licenses: []
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.8.23
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: A thin Ruby wrapper around rsync
|
84
|
+
test_files:
|
85
|
+
- spec/rbrsync_spec.rb
|
86
|
+
- spec/spec_helper.rb
|
87
|
+
- test/test_rbsync.rb
|