ksync 0.5.0 → 0.5.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/README +35 -17
- data/bin/ksync +3 -2
- data/lib/ksync.rb +199 -140
- data/test/test_ksync.rb +40 -11
- metadata +12 -11
data/README
CHANGED
@@ -1,31 +1,49 @@
|
|
1
|
+
=KSync for Ruby/Jruby
|
2
|
+
==Description
|
1
3
|
This gem is a simple folder synchroniser between a changing source folder and a
|
2
4
|
'backup' destination folder (presumed to be unchanged). It uses a list of files hash which is a
|
3
5
|
hash containing the filepath as the key and file information [FileSize, FileMTime] as value.
|
4
6
|
|
5
7
|
In order to compare the source and destination folders:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
hash calculation (inactive by default because it is slow)
|
8
|
+
* It always creates a list of files hash for the source
|
9
|
+
* It uses an existing list of files hash for the destination or creates one if it does not exist
|
10
|
+
* It compares the 2 lists of files hash and copies/deletes from destination accordingly.
|
11
|
+
* It compares files based on size and then on last modification date. It may optionally uses hash calculation (inactive by default because it is slow)
|
11
12
|
|
12
|
-
|
13
|
-
destination and the -u option (use hash) is not specified, then these changes will NOT be detected.
|
14
|
-
This is a fast backup solution and presumes that the destination never changes.
|
13
|
+
The gem comes with a frontend, 'ksync' which can be used directly to invoke the main class.
|
15
14
|
|
16
|
-
|
15
|
+
==Options
|
16
|
+
Following options may be used:
|
17
|
+
# -d or --dry_run : Do a dry run (nothing will be changed) (default : do the real copy)
|
18
|
+
# -v or --verbosity=value : The level of verbosity (1..3) (default = 0 : very silent)
|
19
|
+
# -u or --use_hash : Use hash based calculation of files differences (default : dont use hash)
|
20
|
+
# -f or --force_dest_hash : Force recalculation of files hash in destination folder (default : use existing files hash).
|
21
|
+
# Use this option to still take into account changes done on destination
|
22
|
+
# -h or --help : Display help message
|
23
|
+
==Examples
|
24
|
+
To backup folder c:/dev to c:/dev_backup with default options:
|
17
25
|
|
18
|
-
|
26
|
+
ksync c:/dev c:/dev_backup
|
27
|
+
|
28
|
+
The above, but inside rour ruby code:
|
29
|
+
|
30
|
+
require 'ksync'
|
31
|
+
KSync::Base.new({:src => 'c:/dev', :dst => 'c:/dev_backup'}).do_sync
|
19
32
|
|
20
|
-
To backup folder c:/dev to c:/dev_backup with default options :
|
21
|
-
> ksync c:/dev c:/dev_backup
|
22
|
-
The above, but inside rour ruby code :
|
23
|
-
> require 'ksync'
|
24
|
-
> KSync.new({:src => 'c:/dev', :dst => 'c:/dev_backup'}).do_sync
|
25
33
|
the method do_sync will return false if there were no changes, true otherwise
|
26
34
|
|
27
35
|
To backup folder c:/dev to c:/dev_backup forcing hash calculation (hash calculation will only be used if the files have
|
28
36
|
the same size and modification date):
|
29
|
-
|
37
|
+
ksync --use_hash c:/dev c:/dev_backup
|
30
38
|
or
|
31
|
-
|
39
|
+
ksync -u c:/dev c:/dev_backup
|
40
|
+
|
41
|
+
==Tests
|
42
|
+
To run the tests from the gem folder:
|
43
|
+
rake test
|
44
|
+
|
45
|
+
==Notes
|
46
|
+
If any files in the destination folder have changed then there is no guarantee that the changes will be detected.
|
47
|
+
This is a fast backup solution and presumes that the destination never changes. However, in order to bypass this
|
48
|
+
apparent limitation, the option -f or --force_dest_hash may be used. In this case, the destination folder files hash
|
49
|
+
will be recreated and so will reflect the changes on the destination. The syncing then will take place normally.
|
data/bin/ksync
CHANGED
@@ -17,7 +17,8 @@ o.banner = "Usage: #{$0} [options] source_folder destination_folder"
|
|
17
17
|
o.on('-d', '--dry_run', 'dry run (default : do the real copy - no dry run)') { |s| options[:real_copy] = false }
|
18
18
|
o.on('-v', '--verbosity=value', 'The level of verbosity (1..3) (default = 0 : very silent)') { |s| options[:verbose] = s.to_i }
|
19
19
|
o.on('-u', '--use_hash', 'use hash calculation (default : dont use hash)') { |s| options[:use_hash] = true }
|
20
|
-
o.on('-
|
20
|
+
o.on('-f', '--force_dest_hash', 'force recalculation of files hash in destination folder') { |s| options[:force_dest_hash] = true }
|
21
|
+
o.on('-h', '--help', 'Display this message') { message(o) }
|
21
22
|
|
22
23
|
o.parse!
|
23
24
|
|
@@ -26,5 +27,5 @@ if !ARGV[0] || !ARGV[1]
|
|
26
27
|
else
|
27
28
|
options[:src] = ARGV[0]
|
28
29
|
options[:dst] = ARGV[1]
|
29
|
-
KSync.new(options).do_sync
|
30
|
+
KSync::Base.new(options).do_sync
|
30
31
|
end
|
data/lib/ksync.rb
CHANGED
@@ -1,159 +1,218 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'digest'
|
3
3
|
require 'find'
|
4
|
+
require 'yaml'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
attr_accessor :all_h, :ll
|
11
|
-
def initialize(init_opt)
|
12
|
-
@all_h={}
|
13
|
-
@changes = false
|
14
|
-
init_opt[:real_copy] = init_opt[:real_copy] == nil ? true : init_opt[:real_copy]
|
15
|
-
init_opt[:use_hash] = init_opt[:use_hash] == nil ? false : init_opt[:use_hash]
|
16
|
-
init_opt[:verbose] = init_opt[:verbose] == nil ? 0 : init_opt[:verbose]
|
17
|
-
return nil if !init_opt[:src] | !init_opt[:dst]
|
18
|
-
@options = init_opt
|
19
|
-
@ll = [init_opt[:src], init_opt[:dst]]
|
20
|
-
create_hash
|
21
|
-
end
|
6
|
+
# this is the main KSync module
|
7
|
+
module KSync
|
8
|
+
# this is the only class in the KSync module, needs to be instantiated
|
9
|
+
class Base
|
22
10
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
11
|
+
# index for size of file
|
12
|
+
SSIZE_I=0
|
13
|
+
# index for modification date of file
|
14
|
+
MTIME_I=1
|
15
|
+
|
16
|
+
# the name of the file containing the hash for the destination folder
|
17
|
+
KSYNC_FILES_HASH = '.ksync_files_hash'
|
18
|
+
|
19
|
+
# the version of the ksync gem
|
20
|
+
VERSION = '0.5.1'
|
21
|
+
|
22
|
+
attr_accessor :all_h, :ll
|
23
|
+
# initializes the class
|
24
|
+
def initialize(init_opt)
|
25
|
+
@all_h={}
|
26
|
+
@changes = false
|
27
|
+
init_opt[:real_copy] = init_opt[:real_copy] == nil ? true : init_opt[:real_copy]
|
28
|
+
init_opt[:use_hash] = init_opt[:use_hash] == nil ? false : init_opt[:use_hash]
|
29
|
+
init_opt[:verbose] = init_opt[:verbose] == nil ? 0 : init_opt[:verbose]
|
30
|
+
init_opt[:force_dest_hash] = init_opt[:force_dest_hash] == nil ? false : init_opt[:force_dest_hash]
|
31
|
+
|
32
|
+
return nil if !init_opt[:src] | !init_opt[:dst]
|
33
|
+
@options = init_opt
|
34
|
+
@ll = [init_opt[:src], init_opt[:dst]]
|
35
|
+
create_hash
|
36
|
+
end
|
37
|
+
|
38
|
+
# this method does the actual syncing : frontend
|
39
|
+
def do_sync
|
40
|
+
# browse source hash to detect new and changed files
|
41
|
+
return false unless File.exists?(ll.first)
|
42
|
+
all_h[ll.first].each do |k,v|
|
43
|
+
src_fp = File.join(ll.first,k)
|
44
|
+
dst_fp = File.join(ll.last,k)
|
45
|
+
if !all_h[ll.last][k]
|
46
|
+
copy_del_actions('New', k, src_fp, dst_fp)
|
47
|
+
else
|
48
|
+
if !File.directory?(File.join(ll.first,k))
|
49
|
+
copy_del_actions('Changed',k, src_fp, dst_fp) if !same?(src_fp, dst_fp, v, all_h[ll.last][k])
|
41
50
|
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
# browse destination hash to detect obsolete files
|
46
|
-
@all_h[ll[dst]].each do |k,v|
|
47
|
-
if !all_h[ll[src]][k]
|
48
|
-
dst_fp = File.join(ll[dst],k)
|
49
|
-
puts "D: #{dst_fp}" if @options[:verbose] > 0
|
50
|
-
do_delete dst_fp if @options[:real_copy]
|
51
|
-
@changes = true
|
52
|
-
end
|
53
|
-
end
|
54
|
-
#puts "there were changes" if @changes
|
55
|
-
#puts "nothing changed" if !@changes
|
56
|
-
return @changes
|
57
|
-
end
|
58
|
-
|
59
|
-
def get_hash(in_file)
|
60
|
-
if !File.exists?(in_file)
|
61
|
-
puts "ERR: inexistent file : #{in_file}"
|
62
|
-
return nil
|
63
|
-
end
|
64
|
-
sha1 = Digest::SHA1.new
|
65
|
-
begin
|
66
|
-
File.open(in_file) do |file|
|
67
|
-
buffer = ''
|
68
|
-
# Read the file 512 bytes at a time
|
69
|
-
while not file.eof
|
70
|
-
file.read(512, buffer)
|
71
|
-
sha1.update(buffer)
|
72
51
|
end
|
73
52
|
end
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
begin
|
83
|
-
if File.directory?(src_fp)
|
84
|
-
file_op = "mkdir"
|
85
|
-
FileUtils.mkdir_p dst_fp
|
86
|
-
else
|
87
|
-
file_op = "cp"
|
88
|
-
FileUtils.copy_file src_fp, dst_fp
|
53
|
+
# browse destination hash to detect obsolete files
|
54
|
+
all_h[ll.last].each do |k,v|
|
55
|
+
#next if File.join(ll.last,KSYNC_FILES_HASH) == f # ignore files list hash
|
56
|
+
|
57
|
+
if !all_h[ll.first][k]
|
58
|
+
dst_fp = File.join(ll.last,k)
|
59
|
+
copy_del_actions('Deleted', k, nil, dst_fp )
|
60
|
+
end
|
89
61
|
end
|
90
|
-
|
91
|
-
puts "
|
92
|
-
|
93
|
-
|
62
|
+
#puts "there were changes" if @changes
|
63
|
+
#puts "nothing changed" if !@changes
|
64
|
+
save_files_hash(File.join(ll.last, KSYNC_FILES_HASH)) if @changes and @options[:real_copy] == true
|
65
|
+
return @changes
|
66
|
+
end
|
94
67
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
68
|
+
# saves the files hash to disk
|
69
|
+
def save_files_hash(file)
|
70
|
+
File.open(file, 'w'){|f| f.write all_h[ll.last].to_yaml }
|
71
|
+
end
|
72
|
+
|
73
|
+
#loads the files hash from disk
|
74
|
+
def load_files_hash(file)
|
75
|
+
return YAML::load_file(file)
|
76
|
+
end
|
77
|
+
|
78
|
+
# calculate a hash of a file
|
79
|
+
def get_hash(in_file)
|
80
|
+
if !File.exists?(in_file)
|
81
|
+
puts "ERR: inexistent file : #{in_file}"
|
82
|
+
return nil
|
83
|
+
end
|
84
|
+
sha1 = Digest::SHA1.new
|
85
|
+
begin
|
86
|
+
File.open(in_file) do |file|
|
87
|
+
buffer = ''
|
88
|
+
# Read the file 512 bytes at a time
|
89
|
+
while not file.eof
|
90
|
+
file.read(512, buffer)
|
91
|
+
sha1.update(buffer)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
rescue
|
95
|
+
puts "ERR: while calculating hash for : #{in_file}: (#{$!})"
|
96
|
+
return nil
|
97
|
+
end
|
98
|
+
return sha1.to_s
|
99
|
+
end
|
100
|
+
|
101
|
+
# does the actual copy between source and destination
|
102
|
+
def do_copy(src_fp, dst_fp)
|
103
|
+
begin
|
104
|
+
if File.directory?(src_fp)
|
105
|
+
file_op = "mkdir"
|
106
|
+
FileUtils.mkdir_p dst_fp
|
101
107
|
else
|
102
|
-
file_op =
|
103
|
-
FileUtils.
|
104
|
-
end
|
105
|
-
|
106
|
-
puts "ERR:
|
107
|
-
end
|
108
|
-
rescue
|
109
|
-
puts "ERR: (#{file_op}) for #{dst_fp} : (#{$!})"
|
108
|
+
file_op = "cp"
|
109
|
+
FileUtils.copy_file src_fp, dst_fp
|
110
|
+
end
|
111
|
+
rescue
|
112
|
+
puts "ERR: while copying (#{file_op}) [#{src_fp} to #{dst_fp}] : (#{$!})"
|
113
|
+
end
|
110
114
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
115
|
+
|
116
|
+
# deletes file from destination
|
117
|
+
def do_delete (dst_fp)
|
118
|
+
begin
|
119
|
+
if File.exists?(dst_fp)
|
120
|
+
if File.directory?(dst_fp)
|
121
|
+
file_op = 'remove_dir'
|
122
|
+
FileUtils.remove_dir(dst_fp)
|
123
|
+
else
|
124
|
+
file_op = 'rm'
|
125
|
+
FileUtils.rm dst_fp
|
126
|
+
end
|
127
|
+
else
|
128
|
+
puts "ERR: inexistent file/folder : #{dst_fp}"
|
129
|
+
end
|
130
|
+
rescue
|
131
|
+
puts "ERR: (#{file_op}) for #{dst_fp} : (#{$!})"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# if hash => also check hash if sizes are same
|
136
|
+
def same?(src_fp, dst_fp, src, dst)
|
137
|
+
size_ok = false
|
138
|
+
date_ok = false
|
139
|
+
if src[SSIZE_I] == dst[SSIZE_I] # sizes are the same
|
140
|
+
size_ok = true
|
141
|
+
if dst[MTIME_I] - dst[MTIME_I] >= 0
|
142
|
+
date_ok = true
|
143
|
+
else
|
144
|
+
puts "DATE diff for #{src_fp} vs #{dst_fp}" if @options[:verbose] > 1
|
145
|
+
end
|
121
146
|
else
|
122
|
-
puts "
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
return false
|
147
|
+
puts "SIZE diff for #{src_fp} vs #{dst_fp}" if @options[:verbose] > 1
|
148
|
+
end
|
149
|
+
return false if !size_ok
|
150
|
+
return false if !date_ok
|
151
|
+
return true if !@options[:use_hash]
|
152
|
+
h1 = get_hash(src_fp)
|
153
|
+
h2 = get_hash(dst_fp)
|
154
|
+
if h1 != h2
|
155
|
+
puts "SHA1 diff for #{src_fp} vs #{dst_fp}" if @options[:verbose] > 1
|
156
|
+
return false
|
157
|
+
end
|
158
|
+
return true
|
135
159
|
end
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
160
|
+
|
161
|
+
#creates the initial file list hash for the source and potentially the destination
|
162
|
+
def create_hash
|
163
|
+
if !File.exists?(ll.first)
|
164
|
+
puts "source folder #{ll.first} does not exist ! "
|
165
|
+
return
|
166
|
+
end
|
167
|
+
ll.each do |prefix|
|
168
|
+
all_h[prefix] = {}
|
169
|
+
if prefix == ll.last
|
170
|
+
next if @options[:real_copy] == false
|
171
|
+
dest_hash_file_name = File.join(ll.last,KSYNC_FILES_HASH)
|
172
|
+
if File.exists?(dest_hash_file_name) && @options[:force_dest_hash] == false
|
173
|
+
all_h[prefix] = load_files_hash(dest_hash_file_name)
|
174
|
+
next unless @options[:force_dest_hash]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
cnt = 0
|
179
|
+
if !File.exists?(prefix)
|
180
|
+
puts "creating folder #{prefix}" if @options[:verbose] > 1
|
181
|
+
FileUtils.mkdir_p prefix
|
182
|
+
end
|
183
|
+
|
184
|
+
Find.find(prefix).each do |f|
|
185
|
+
next if prefix == f
|
186
|
+
ff = f.unpack('U*').pack('U*') # to get rid of funny encoding related errors
|
187
|
+
all_h[prefix][ff.split(prefix)[1]] = [File.size(ff), File.mtime(ff)]
|
188
|
+
puts "(#{ff})" if @options[:verbose] > 2
|
189
|
+
puts cnt if cnt % 100 == 0 && @options[:verbose] > 1
|
190
|
+
cnt += 1
|
191
|
+
end
|
192
|
+
|
193
|
+
save_files_hash(File.join(ll.last, KSYNC_FILES_HASH)) if prefix == ll.last
|
194
|
+
|
195
|
+
end
|
142
196
|
end
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
197
|
+
|
198
|
+
private
|
199
|
+
|
200
|
+
def copy_del_actions(action, k, src_fp, dst_fp)
|
201
|
+
puts "#{action}: #{k}" if @options[:verbose] > 0
|
202
|
+
if action == 'Deleted'
|
203
|
+
if @options[:real_copy]
|
204
|
+
do_delete dst_fp
|
205
|
+
all_h[ll.last].delete(k)
|
206
|
+
end
|
207
|
+
else
|
208
|
+
if @options[:real_copy]
|
209
|
+
do_copy(src_fp, dst_fp) if @options[:real_copy]
|
210
|
+
all_h[ll.last][k] = [File.size(dst_fp), File.mtime(dst_fp)]
|
211
|
+
end
|
156
212
|
end
|
213
|
+
@changes = true unless @changes
|
157
214
|
end
|
215
|
+
|
216
|
+
|
158
217
|
end
|
159
218
|
end
|
data/test/test_ksync.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
gem 'minitest', '
|
1
|
+
gem 'minitest', '~> 4.4' # use the gem version, not the 1.9 bundled version of minitest
|
2
2
|
require 'minitest/autorun'
|
3
3
|
|
4
4
|
require 'ksync'
|
@@ -9,7 +9,8 @@ require 'turn'
|
|
9
9
|
Turn.config.format = :outline
|
10
10
|
|
11
11
|
class KSyncTest < MiniTest::Unit::TestCase
|
12
|
-
|
12
|
+
include KSync
|
13
|
+
def setup
|
13
14
|
begin
|
14
15
|
@src_path = File.join(File.dirname(__FILE__), "src/folder1/folder2")
|
15
16
|
@dst_path = File.join(File.dirname(__FILE__), "src")
|
@@ -19,7 +20,8 @@ class KSyncTest < MiniTest::Unit::TestCase
|
|
19
20
|
rescue
|
20
21
|
puts "error trying to do the setup :#{$!}"
|
21
22
|
end
|
22
|
-
|
23
|
+
end
|
24
|
+
|
23
25
|
def teardown
|
24
26
|
FileUtils.rm_rf @opts[:src]
|
25
27
|
FileUtils.rm_rf @opts[:dst]
|
@@ -30,6 +32,7 @@ class KSyncTest < MiniTest::Unit::TestCase
|
|
30
32
|
l1 = File.join(File.dirname(__FILE__), base_path)
|
31
33
|
l2 = File.join(File.dirname(__FILE__), "#{base_path}/folder1")
|
32
34
|
l3 = File.join(File.dirname(__FILE__), "#{base_path}/folder1/folder2")
|
35
|
+
l4 = File.join(File.dirname(__FILE__), "#{base_path}/folder_empty")
|
33
36
|
FileUtils.mkdir_p File.join(File.dirname(__FILE__),File.join(base_path, "/folder1/folder2"))
|
34
37
|
# create some files and write some content
|
35
38
|
[l1,l2,l3].each do |folder|
|
@@ -60,34 +63,46 @@ class KSyncTest < MiniTest::Unit::TestCase
|
|
60
63
|
end
|
61
64
|
|
62
65
|
# tests
|
63
|
-
def
|
66
|
+
def test_new_tree
|
64
67
|
assert_equal(File.exists?(@opts[:dst]), false, "initial conditions not correct")
|
65
|
-
KSync.new(@opts).do_sync
|
68
|
+
KSync::Base.new(@opts).do_sync
|
66
69
|
assert_equal(compare_folders(@opts[:src], @opts[:dst]), true)
|
67
70
|
end
|
68
71
|
|
69
72
|
def test_nothing_changed
|
70
73
|
create_tree("dst")
|
71
74
|
assert_equal(compare_folders(@opts[:src], @opts[:dst]), true)
|
72
|
-
assert_equal(KSync.new(@opts).do_sync, false)
|
75
|
+
assert_equal(KSync::Base.new(@opts).do_sync, false)
|
73
76
|
end
|
74
77
|
|
75
78
|
def test_more_files_in_source
|
76
79
|
create_fill_file(File.join(@opts[:src],"NEWFILE.txt"))
|
77
|
-
assert_equal(KSync.new(@opts).do_sync, true)
|
80
|
+
assert_equal(KSync::Base.new(@opts).do_sync, true)
|
81
|
+
assert_equal(compare_folders(@opts[:src], @opts[:dst]), true)
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_more_folders_in_source
|
85
|
+
FileUtils.mkdir_p (File.join(@opts[:src],"NEW_FOLDER/NEW_FOLDER"))
|
86
|
+
assert_equal(KSync::Base.new(@opts).do_sync, true)
|
78
87
|
assert_equal(compare_folders(@opts[:src], @opts[:dst]), true)
|
79
88
|
end
|
80
89
|
|
81
90
|
def test_less_files_in_source
|
82
91
|
FileUtils.rm(File.join(@opts[:src],"File01"))
|
83
|
-
assert_equal(KSync.new(@opts).do_sync, true)
|
92
|
+
assert_equal(KSync::Base.new(@opts).do_sync, true)
|
93
|
+
assert_equal(compare_folders(@opts[:src], @opts[:dst]), true)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_less_folders_in_source
|
97
|
+
FileUtils.rm_rf "#{@opts[:src]}/folder_empty"
|
98
|
+
assert_equal(KSync::Base.new(@opts).do_sync, true)
|
84
99
|
assert_equal(compare_folders(@opts[:src], @opts[:dst]), true)
|
85
100
|
end
|
86
101
|
|
87
102
|
def test_source_file_changed_using_hash
|
88
103
|
create_fill_file(File.join(@opts[:src],"File01"))
|
89
104
|
@opts[:use_hash] = true
|
90
|
-
assert_equal(KSync.new(@opts).do_sync, true)
|
105
|
+
assert_equal(KSync::Base.new(@opts).do_sync, true)
|
91
106
|
assert_equal(compare_folders(@opts[:src], @opts[:dst]), true)
|
92
107
|
end
|
93
108
|
|
@@ -95,15 +110,29 @@ class KSyncTest < MiniTest::Unit::TestCase
|
|
95
110
|
@opts2 = {:src => File.join(File.dirname(__FILE__), "src_non"), :dst => File.join(File.dirname(__FILE__), "dst_non")}
|
96
111
|
assert_equal(File.exists?(@opts2[:src]), false, "initial conditions not correct")
|
97
112
|
@opts2[:verbose] = 3
|
98
|
-
assert_equal(KSync.new(@opts2).do_sync, false)
|
113
|
+
assert_equal(KSync::Base.new(@opts2).do_sync, false)
|
99
114
|
end
|
100
115
|
|
101
116
|
def test_dry_run
|
102
117
|
assert_equal(File.exists?(@opts[:dst]), false, "initial conditions not correct")
|
103
118
|
@opts[:real_copy] = false
|
104
119
|
@opts[:verbose] = 3
|
105
|
-
|
120
|
+
@opts[:force_dest_hash] = true
|
121
|
+
KSync::Base.new(@opts).do_sync
|
106
122
|
assert_equal(File.exists?(@opts[:dst]), false)
|
107
123
|
end
|
108
124
|
|
125
|
+
def test_use_existing_files_hash
|
126
|
+
assert_equal(File.exists?(@opts[:dst]), false, "initial conditions not correct")
|
127
|
+
k = KSync::Base.new(@opts)
|
128
|
+
k.do_sync
|
129
|
+
assert_equal(compare_folders(@opts[:src], @opts[:dst]), true)
|
130
|
+
saved_hash = File.open(File.join(@opts[:dst], KSync::Base::KSYNC_FILES_HASH),'r').read
|
131
|
+
teardown
|
132
|
+
setup
|
133
|
+
File.open(File.join(@opts[:dst], KSync::Base::KSYNC_FILES_HASH),'w'){|f| f.write saved_hash}
|
134
|
+
assert_equal(KSync::Base.new(@opts).do_sync, false)
|
135
|
+
FileUtils.rm File.join(@opts[:dst], KSync::Base::KSYNC_FILES_HASH) rescue nil
|
136
|
+
end
|
137
|
+
|
109
138
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ksync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -15,25 +15,25 @@ dependencies:
|
|
15
15
|
name: turn
|
16
16
|
version_requirements: &2056 !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ~>
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '0'
|
20
|
+
version: '0.9'
|
21
21
|
none: false
|
22
22
|
requirement: *2056
|
23
23
|
prerelease: false
|
24
|
-
type: :
|
24
|
+
type: :development
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: minitest
|
27
27
|
version_requirements: &2074 !ruby/object:Gem::Requirement
|
28
28
|
requirements:
|
29
|
-
- -
|
29
|
+
- - ~>
|
30
30
|
- !ruby/object:Gem::Version
|
31
|
-
version: 4.4
|
31
|
+
version: '4.4'
|
32
32
|
none: false
|
33
33
|
requirement: *2074
|
34
34
|
prerelease: false
|
35
|
-
type: :
|
36
|
-
description: ksync is a simple
|
35
|
+
type: :development
|
36
|
+
description: ksync is a simple class which is used to sync between 2 folders, the destination folder being used as a backup repository
|
37
37
|
email: kiriakos.adoniadis@gmail.com
|
38
38
|
executables:
|
39
39
|
- ksync
|
@@ -42,11 +42,11 @@ extra_rdoc_files:
|
|
42
42
|
- README
|
43
43
|
- MIT-LICENSE
|
44
44
|
files:
|
45
|
+
- README
|
46
|
+
- MIT-LICENSE
|
45
47
|
- Rakefile.rb
|
46
48
|
- lib/ksync.rb
|
47
49
|
- bin/ksync
|
48
|
-
- README
|
49
|
-
- MIT-LICENSE
|
50
50
|
- test/test_ksync.rb
|
51
51
|
homepage: http://rubygems.org/gems/ksync
|
52
52
|
licenses:
|
@@ -72,7 +72,8 @@ rubyforge_project:
|
|
72
72
|
rubygems_version: 1.8.9
|
73
73
|
signing_key:
|
74
74
|
specification_version: 3
|
75
|
-
summary:
|
75
|
+
summary: A simple file backup/syncing class
|
76
76
|
test_files:
|
77
77
|
- test/test_ksync.rb
|
78
|
+
has_rdoc:
|
78
79
|
...
|