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.
Files changed (5) hide show
  1. data/README +35 -17
  2. data/bin/ksync +3 -2
  3. data/lib/ksync.rb +199 -140
  4. data/test/test_ksync.rb +40 -11
  5. 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
- a. it always creates a list of files hash for the source
7
- b. it uses an existing list of files hash for the destination or creates one if non existing
8
- c. It compares the 2 lists of files hash and copies/deletes from destination accordingly.
9
- d. It compares files based on size and then on last modification date. It may optionally use
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
- NOTE: If any files in the destination folder have changed and the files hash exists in the
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
- The gem comes with a frontend, 'ksync' which can be used directly to invoke the object
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
- Examples of usage:
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
- > ksync --use_hash c:/dev c:/dev_backup
37
+ ksync --use_hash c:/dev c:/dev_backup
30
38
  or
31
- > ksync -u c:/dev c:/dev_backup
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('-h', '--help') { message(o) }
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
- class KSync
6
-
7
- SSIZE_I=0
8
- MTIME_I=1
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
- def do_sync
24
- src=0
25
- dst=1
26
- # browse source hash to detect new and changed files
27
- return false unless File.exists?(ll.first)
28
- @all_h[ll[src]].each do |k,v|
29
- src_fp = File.join(@ll[src],k)
30
- dst_fp = File.join(@ll[dst],k)
31
- if !@all_h[@ll[dst]][k]
32
- puts "N: #{k}" if @options[:verbose] > 0
33
- do_copy(src_fp, dst_fp, v) if @options[:real_copy]
34
- @changes = true
35
- else
36
- if !File.directory?(File.join(@ll[src],k))
37
- if !same?(src_fp, dst_fp, v, all_h[@ll[dst]][k])
38
- puts "C: #{k}" if @options[:verbose] > 0
39
- do_copy(src_fp, dst_fp, v) if @options[:real_copy]
40
- @changes = true
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
- rescue
75
- puts "ERR: while calculating hash for : #{in_file}: (#{$!})"
76
- return nil
77
- end
78
- return sha1.to_s
79
- end
80
-
81
- def do_copy(src_fp, dst_fp, src)
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
- rescue
91
- puts "ERR: while copying (#{file_op}) [#{src_fp} to #{dst_fp}] : (#{$!})"
92
- end
93
- end
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
- def do_delete (dst_fp)
96
- begin
97
- if File.exists?(dst_fp)
98
- if File.directory?(dst_fp)
99
- file_op = 'remove_dir'
100
- FileUtils.remove_dir(dst_fp)
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 = 'rm'
103
- FileUtils.rm dst_fp
104
- end
105
- else
106
- puts "ERR: inexistent file/folder : #{dst_fp}"
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
- end
112
-
113
- # if hash => also check hash if sizes are same
114
- def same?(src_fp, dst_fp, src, dst)
115
- size_ok = false
116
- date_ok = false
117
- if src[SSIZE_I] == dst[SSIZE_I] # sizes are the same
118
- size_ok = true
119
- if dst[MTIME_I] - dst[MTIME_I] >= 0
120
- date_ok = true
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 "DATE diff for #{src_fp} vs #{dst_fp}" if @options[:verbose] > 1
123
- end
124
- else
125
- puts "SIZE diff for #{src_fp} vs #{dst_fp}" if @options[:verbose] > 1
126
- end
127
- return false if !size_ok
128
- return false if !date_ok
129
- return true if !@options[:use_hash]
130
- h1 = get_hash(src_fp)
131
- h2 = get_hash(dst_fp)
132
- if h1 != h2
133
- puts "SHA1 diff for #{src_fp} vs #{dst_fp}" if @options[:verbose] > 1
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
- return true
137
- end
138
- def create_hash
139
- if !File.exists?(@ll.first)
140
- puts "source folder #{@ll.first} does not exist ! "
141
- return
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
- @ll.each do |prefix|
144
- @all_h[prefix] = {}
145
- next if prefix == @ll.last && @options[:real_copy] == false
146
- puts "creating hash for #{prefix}" if @options[:verbose] > 1
147
- cnt = 0
148
- FileUtils.mkdir_p prefix if !File.exists?(prefix)
149
- Find.find(prefix).each do |f|
150
- next if prefix == f
151
- ff = f.unpack('U*').pack('U*') # to get rid of funny encoding related errors
152
- @all_h[prefix][ff.split(prefix)[1]] = [File.size(ff), File.mtime(ff)]
153
- puts "(#{ff})" if @options[:verbose] > 2
154
- puts cnt if cnt % 100 == 0 && @options[:verbose] > 2
155
- cnt += 1
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', '>= 4.4.0' # use the gem version, not the 1.9 bundled version of 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
- def setup
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
- end
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 test_new
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
- KSync.new(@opts).do_sync
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.0
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: :runtime
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.0
31
+ version: '4.4'
32
32
  none: false
33
33
  requirement: *2074
34
34
  prerelease: false
35
- type: :runtime
36
- description: ksync is a simple script which is used to sync between 2 folders, the destination folder being used as a repository
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: ! 'Ksync: A simple file backup/syncing class'
75
+ summary: A simple file backup/syncing class
76
76
  test_files:
77
77
  - test/test_ksync.rb
78
+ has_rdoc:
78
79
  ...