rsync 0.0.1
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/.gitignore +17 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +20 -0
- data/Rakefile +4 -0
- data/lib/rsync.rb +13 -0
- data/lib/rsync/change.rb +146 -0
- data/lib/rsync/command.rb +19 -0
- data/lib/rsync/result.rb +65 -0
- data/lib/rsync/version.rb +3 -0
- data/rsync.gemspec +23 -0
- data/spec/rsync/change_spec.rb +42 -0
- metadata +120 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Joshua Bussdieker
|
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,20 @@
|
|
1
|
+
# Rsync
|
2
|
+
|
3
|
+
[](https://travis-ci.org/jbussdieker/ruby-rsync)
|
4
|
+
|
5
|
+
Ruby/Rsync is a Ruby library that can syncronize files between remote hosts by wrapping a call to the rsync binary.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
require "rsync"
|
10
|
+
|
11
|
+
Rsync.command(["/path/to/source", "/path/to/destination"]) do |result|
|
12
|
+
if result.success?
|
13
|
+
result.changes.each do |change|
|
14
|
+
puts "#{change.filename} (#{change.summary})"
|
15
|
+
end
|
16
|
+
else
|
17
|
+
puts result.error
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
data/Rakefile
ADDED
data/lib/rsync.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "rsync/version"
|
2
|
+
require "rsync/command"
|
3
|
+
require "rsync/result"
|
4
|
+
|
5
|
+
module Rsync
|
6
|
+
def self.command(args = [], &block)
|
7
|
+
output = Command.new(args).run
|
8
|
+
exitcode = $?
|
9
|
+
result = Result.new(output, exitcode)
|
10
|
+
yield(result) if block_given?
|
11
|
+
result
|
12
|
+
end
|
13
|
+
end
|
data/lib/rsync/change.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
module Rsync
|
2
|
+
class Change
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(raw)
|
6
|
+
@raw = raw
|
7
|
+
end
|
8
|
+
|
9
|
+
def each(&block)
|
10
|
+
@raw.split("\n").each do |line|
|
11
|
+
#if line =~ /^([<>ch.*][fdLDS][ .+\?cstTpoguax]{9}) (.*)$/
|
12
|
+
if line =~ /^([<>ch.\*].{10}) (.*)$/
|
13
|
+
detail = Detail.new(line)
|
14
|
+
yield(detail) if detail.changed?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Detail
|
20
|
+
def initialize(raw)
|
21
|
+
@raw = raw
|
22
|
+
end
|
23
|
+
|
24
|
+
def filename
|
25
|
+
@raw[12..-1]
|
26
|
+
end
|
27
|
+
|
28
|
+
def changed?
|
29
|
+
if update_type == :message
|
30
|
+
return true
|
31
|
+
elsif update_type == :recv
|
32
|
+
return true
|
33
|
+
end
|
34
|
+
false
|
35
|
+
end
|
36
|
+
|
37
|
+
def summary
|
38
|
+
if update_type == :message
|
39
|
+
message
|
40
|
+
elsif update_type == :recv and @raw[2,9] == "+++++++++"
|
41
|
+
"creating"
|
42
|
+
elsif update_type == :recv
|
43
|
+
"updating"
|
44
|
+
else
|
45
|
+
changes = []
|
46
|
+
#[:checksum, :size, :timestamp, :permissions, :owner, :group, :acl].each do |prop|
|
47
|
+
[:checksum, :size, :permissions, :owner, :group, :acl].each do |prop|
|
48
|
+
changes << prop if send(prop) == :changed
|
49
|
+
end
|
50
|
+
changes.join(", ")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def message
|
55
|
+
@raw[1..10].strip
|
56
|
+
end
|
57
|
+
|
58
|
+
def raw_update_type
|
59
|
+
@raw[0,1]
|
60
|
+
end
|
61
|
+
|
62
|
+
def raw_file_type
|
63
|
+
@raw[1,1]
|
64
|
+
end
|
65
|
+
|
66
|
+
def attribute_prop(index)
|
67
|
+
case @raw[index,1]
|
68
|
+
when '.'
|
69
|
+
:no_change
|
70
|
+
when ' '
|
71
|
+
:identical
|
72
|
+
when '+'
|
73
|
+
:new
|
74
|
+
when '?'
|
75
|
+
:unknown
|
76
|
+
else
|
77
|
+
:changed
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def checksum
|
82
|
+
attribute_prop(2)
|
83
|
+
end
|
84
|
+
|
85
|
+
def size
|
86
|
+
attribute_prop(3)
|
87
|
+
end
|
88
|
+
|
89
|
+
def timestamp
|
90
|
+
attribute_prop(4)
|
91
|
+
end
|
92
|
+
|
93
|
+
def permissions
|
94
|
+
attribute_prop(5)
|
95
|
+
end
|
96
|
+
|
97
|
+
def owner
|
98
|
+
attribute_prop(6)
|
99
|
+
end
|
100
|
+
|
101
|
+
def group
|
102
|
+
attribute_prop(7)
|
103
|
+
end
|
104
|
+
|
105
|
+
def acl
|
106
|
+
attribute_prop(9)
|
107
|
+
end
|
108
|
+
|
109
|
+
def ext_attr
|
110
|
+
attribute_prop(10)
|
111
|
+
end
|
112
|
+
|
113
|
+
def update_type
|
114
|
+
case raw_update_type
|
115
|
+
when '<'
|
116
|
+
:sent
|
117
|
+
when '>'
|
118
|
+
:recv
|
119
|
+
when 'c'
|
120
|
+
:change
|
121
|
+
when 'h'
|
122
|
+
:hard_link
|
123
|
+
when '.'
|
124
|
+
:no_update
|
125
|
+
when '*'
|
126
|
+
:message
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def file_type
|
131
|
+
case raw_file_type
|
132
|
+
when 'f'
|
133
|
+
:file
|
134
|
+
when 'd'
|
135
|
+
:directory
|
136
|
+
when 'L'
|
137
|
+
:symlink
|
138
|
+
when 'D'
|
139
|
+
:device
|
140
|
+
when 'S'
|
141
|
+
:special
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Rsync
|
2
|
+
class Command
|
3
|
+
def initialize(args)
|
4
|
+
@args = args.join(" ")
|
5
|
+
end
|
6
|
+
|
7
|
+
def run
|
8
|
+
run_command("rsync --itemize-changes #{@args}")
|
9
|
+
end
|
10
|
+
|
11
|
+
def run_command(cmd, &block)
|
12
|
+
if block_given?
|
13
|
+
IO.popen("#{cmd} 2>&1", &block)
|
14
|
+
else
|
15
|
+
`#{cmd} 2>&1`
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/rsync/result.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'rsync/change'
|
2
|
+
|
3
|
+
module Rsync
|
4
|
+
class Result
|
5
|
+
def initialize(raw, exitcode)
|
6
|
+
@raw = raw
|
7
|
+
@exitcode = exitcode
|
8
|
+
end
|
9
|
+
|
10
|
+
def success?
|
11
|
+
@exitcode.to_i == 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def error
|
15
|
+
case @exitcode.exitstatus
|
16
|
+
when 0
|
17
|
+
"Success"
|
18
|
+
when 1
|
19
|
+
"Syntax or usage error"
|
20
|
+
when 2
|
21
|
+
"Protocol incompatibility"
|
22
|
+
when 3
|
23
|
+
"Errors selecting input/output files, dirs"
|
24
|
+
when 4
|
25
|
+
"Requested action not supported: an attempt was made to manipulate 64-bit files on a platform that can not support them; or an option was specified that is supported by the client and not by the server."
|
26
|
+
when 5
|
27
|
+
"Error starting client-server protocol"
|
28
|
+
when 6
|
29
|
+
"Daemon unable to append to log-file"
|
30
|
+
when 10
|
31
|
+
"Error in socket I/O"
|
32
|
+
when 11
|
33
|
+
"Error in file I/O"
|
34
|
+
when 12
|
35
|
+
"Error in rsync protocol data stream"
|
36
|
+
when 13
|
37
|
+
"Errors with program diagnostics"
|
38
|
+
when 14
|
39
|
+
"Error in IPC code"
|
40
|
+
when 20
|
41
|
+
"Received SIGUSR1 or SIGINT"
|
42
|
+
when 21
|
43
|
+
"Some error returned by waitpid()"
|
44
|
+
when 22
|
45
|
+
"Error allocating core memory buffers"
|
46
|
+
when 23
|
47
|
+
"Partial transfer due to error"
|
48
|
+
when 24
|
49
|
+
"Partial transfer due to vanished source files"
|
50
|
+
when 25
|
51
|
+
"The --max-delete limit stopped deletions"
|
52
|
+
when 30
|
53
|
+
"Timeout in data send/receive"
|
54
|
+
when 35
|
55
|
+
"Timeout waiting for daemon connection"
|
56
|
+
else
|
57
|
+
"Unknown Error"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def changes
|
62
|
+
Change.new(@raw)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/rsync.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rsync/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rsync"
|
8
|
+
spec.version = Rsync::VERSION
|
9
|
+
spec.authors = ["Joshua Bussdieker"]
|
10
|
+
spec.email = ["jbussdieker@gmail.com"]
|
11
|
+
spec.summary = %q{Ruby/Rsync is a Ruby library that can syncronize files between remote hosts by wrapping a call to the rsync binary.}
|
12
|
+
spec.homepage = "http://github.com/jbussdieker/ruby-rsync"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
spec.add_development_dependency "rspec"
|
23
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rsync/change'
|
2
|
+
|
3
|
+
describe Rsync::Change do
|
4
|
+
it "should handle example" do
|
5
|
+
Rsync::Change.new(".f blah2.txt")
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Rsync::Change::Detail do
|
10
|
+
it "should handle filename" do
|
11
|
+
Rsync::Change::Detail.new(" filename").filename.should eql("filename")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should handle message type" do
|
15
|
+
Rsync::Change::Detail.new("*deleting ").message.should eql("deleting")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should handle update types" do
|
19
|
+
Rsync::Change::Detail.new("< ").update_type.should eql(:sent)
|
20
|
+
Rsync::Change::Detail.new("> ").update_type.should eql(:recv)
|
21
|
+
Rsync::Change::Detail.new("c ").update_type.should eql(:change)
|
22
|
+
Rsync::Change::Detail.new("h ").update_type.should eql(:hard_link)
|
23
|
+
Rsync::Change::Detail.new(". ").update_type.should eql(:no_update)
|
24
|
+
Rsync::Change::Detail.new("* ").update_type.should eql(:message)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should handle file types" do
|
28
|
+
Rsync::Change::Detail.new(" f ").file_type.should eql(:file)
|
29
|
+
Rsync::Change::Detail.new(" d ").file_type.should eql(:directory)
|
30
|
+
Rsync::Change::Detail.new(" L ").file_type.should eql(:symlink)
|
31
|
+
Rsync::Change::Detail.new(" D ").file_type.should eql(:device)
|
32
|
+
Rsync::Change::Detail.new(" S ").file_type.should eql(:special)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should handle checksum info" do
|
36
|
+
Rsync::Change::Detail.new(" c ").checksum.should eql(:changed)
|
37
|
+
Rsync::Change::Detail.new(" . ").checksum.should eql(:no_change)
|
38
|
+
Rsync::Change::Detail.new(" ").checksum.should eql(:identical)
|
39
|
+
Rsync::Change::Detail.new(" + ").checksum.should eql(:new)
|
40
|
+
Rsync::Change::Detail.new(" ? ").checksum.should eql(:unknown)
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rsync
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Joshua Bussdieker
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2013-07-23 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: bundler
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 9
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 3
|
32
|
+
version: "1.3"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rake
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rspec
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :development
|
62
|
+
version_requirements: *id003
|
63
|
+
description:
|
64
|
+
email:
|
65
|
+
- jbussdieker@gmail.com
|
66
|
+
executables: []
|
67
|
+
|
68
|
+
extensions: []
|
69
|
+
|
70
|
+
extra_rdoc_files: []
|
71
|
+
|
72
|
+
files:
|
73
|
+
- .gitignore
|
74
|
+
- .travis.yml
|
75
|
+
- Gemfile
|
76
|
+
- LICENSE.txt
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
79
|
+
- lib/rsync.rb
|
80
|
+
- lib/rsync/change.rb
|
81
|
+
- lib/rsync/command.rb
|
82
|
+
- lib/rsync/result.rb
|
83
|
+
- lib/rsync/version.rb
|
84
|
+
- rsync.gemspec
|
85
|
+
- spec/rsync/change_spec.rb
|
86
|
+
homepage: http://github.com/jbussdieker/ruby-rsync
|
87
|
+
licenses:
|
88
|
+
- MIT
|
89
|
+
post_install_message:
|
90
|
+
rdoc_options: []
|
91
|
+
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
hash: 3
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
version: "0"
|
112
|
+
requirements: []
|
113
|
+
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 1.8.15
|
116
|
+
signing_key:
|
117
|
+
specification_version: 3
|
118
|
+
summary: Ruby/Rsync is a Ruby library that can syncronize files between remote hosts by wrapping a call to the rsync binary.
|
119
|
+
test_files:
|
120
|
+
- spec/rsync/change_spec.rb
|