ksync 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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
  ...