sundae 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ doc
10
+ rdoc
11
+ spec/reports
12
+ test/tmp
13
+ test/version_tmp
14
+ tmp
15
+
16
+ # YARD artifacts
17
+ .yardoc
18
+ _yardoc
19
+ doc/
data/README.rdoc CHANGED
@@ -38,6 +38,10 @@ works. Like this:
38
38
  ~> ls
39
39
  bin Desktop doc etc lib local mnt share src tmp var WualaDrive
40
40
 
41
+ And that's it. When called, Sundae creates links so that you can
42
+ work on your files from seperate parts of life as if they were side
43
+ by side.
44
+
41
45
  == Install
42
46
 
43
47
  sudo gem install sundae
@@ -66,16 +70,22 @@ this:
66
70
  `-- collection2/
67
71
  ` ...
68
72
 
69
- Why is this double layer "collection" stuff going on? Because while
70
- most of the time you can share a whole folder between computers,
71
- sometimes you want to mix your config files into a folder that also
72
- contains nonsymlinked files.
73
+ Sundae will act on all of the <em>mnt</em>s--subdirectories of the
74
+ <em>collection</em>s, that is, the sub-subdirectories of the
75
+ <em>path</em>. The "collections" are only there to facilitate
76
+ grouping common files and syncronizing them between computers.
73
77
 
74
- For example, your ~/.ssh folder probably has a public and private key
75
- that you want to stay unique to that machine, but you might want to
76
- mix in a "config" file that has host aliases that you share between
77
- machines. This is how you do that. I do it with my .unison, .mocp,
78
- .ssh, and .lftp folders.
78
+ By default, all of the contents in each of the <em>mnt</em>s are
79
+ placed in the user's home directory. This can be altered by creating
80
+ a file called <tt>.sundae_path</tt> in the top of the <em>mnt</em>;
81
+ the file should contain one line, which is the absolute path to where
82
+ that directory should be "mounted."
83
+
84
+ There's one exception to the "by default everything is placed in the
85
+ home directory" rule. If the mnt directory starts with "dot-" or
86
+ "dot_" then it is placed in the dot folder formed using the rest of
87
+ the name. For example, the files in a "dot-ssh" mnt are placed in
88
+ "~/.ssh" by default.
79
89
 
80
90
  For example, the hierarchy in my <em>path</em>s looks sort of like this:
81
91
 
@@ -86,13 +96,13 @@ For example, the hierarchy in my <em>path</em>s looks sort of like this:
86
96
  | | |-- etc/ (~/etc will point here)
87
97
  | | ` ...
88
98
  | |-- dot-unison
89
- | | |-- .sundae_path (says "~/.unison")
99
+ | | |-- .sundae_path (says "~/.unison", but not required)
90
100
  | | |-- default.prf (~/.unison/default.prf will point here)
91
101
  | | `
92
102
  | |
93
103
  |-- osx/
94
- | |-- home_library/ (says "~/Library")
95
- | | |-- .sundae_path
104
+ | |-- home_library/
105
+ | | |-- .sundae_path (says "~/Library", required)
96
106
  | | `-- Library-Keyboard_Layouts/
97
107
  | | `-- Keyboard Layouts/
98
108
  | | ` Colemak.keylayout
@@ -112,20 +122,30 @@ For example, the hierarchy in my <em>path</em>s looks sort of like this:
112
122
  | ` ...
113
123
  ` ...
114
124
 
115
- Sundae will act on all of the <em>mnt</em>s--subdirectories of the
116
- <em>collection</em>s, that is, the sub-subdirectories of the
117
- <em>path</em>. The "collections" are only there to facilitate
118
- grouping common files and syncronizing them between computers.
119
-
120
- By default, all of the contents in each of the <em>mnt</em>s are
121
- placed in the user's home directory. This can be altered by
122
- creating a file called <tt>.sundae_path</tt> in the top of the
123
- <em>mnt</em>; the file should contain one line, which is the
124
- absolute path to where that directory should be "mounted."
125
+ Why is this double layer "collection" stuff going on? Because while
126
+ most of the time you can share a whole folder between computers,
127
+ sometimes you want to mix your config files into a folder that also
128
+ contains nonsymlinked files.
125
129
 
126
- And that's it. When called, Sundae creates links so that you can
127
- work on your files from seperate parts of life as if they were side
128
- by side.
130
+ For example, your ~/.ssh folder probably has a public and private key
131
+ that you want to stay unique to that machine, but you might want to
132
+ mix in a "config" file that has host aliases that you share between
133
+ machines. You can put the file in "~/mnt/nix/.ssh/config" in the
134
+ above example, and it will get created alongside the other static
135
+ files in the "~/.ssh/" directory.
136
+
137
+ However, every time you run sundae it will check the target locations
138
+ of each file and directory (recursively) in every mnt directory for
139
+ dangling symlinks and other stuff that sundae might have created. If
140
+ you put the the file in "~/mnt/nix/dot-ssh/config", it will be placed
141
+ in the correct place and only "config" will be checked when sundae is
142
+ run (not all of the other files in "~/.ssh/").
143
+
144
+ It obviously doesn't make much of a speed difference in this case, but
145
+ if you're mixing in one file into "~/a/b/c/d/file", and there are lots
146
+ of files beneath "~/a/", then you don't want sundae to look through
147
+ everything every time it runs. Just put it in a mnt directory with a
148
+ <tt>.sundae_path</tt> of "~/a/b/c/d".
129
149
 
130
150
  == Author
131
151
  <don@ohspite.net>
data/lib/sundae.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  require 'configatron'
3
3
  require 'fileutils'
4
4
  require 'find'
5
+ require 'pathname'
5
6
 
6
7
  # A collection of methods to mix the contents of several directories
7
8
  # together using symbolic links.
@@ -13,20 +14,21 @@ module Sundae
13
14
  # :startdoc:
14
15
  VERSION = ::File.read(PATH + 'version.txt').strip
15
16
 
16
- DEFAULT_CONFIG_FILE = File.expand_path(File.join(ENV['HOME'], '.sundae'))
17
+ DEFAULT_CONFIG_FILE = (Pathname.new(Dir.home) + '.sundae').expand_path
17
18
 
18
19
  @config_file = DEFAULT_CONFIG_FILE
19
20
 
20
21
  # Read configuration from <tt>.sundae</tt>.
21
22
  #
22
23
  def self.load_config_file(config_file = DEFAULT_CONFIG_FILE)
23
- config_file ||= DEFAULT_CONFIG_FILE
24
- config_file = File.join(config_file, '.sundae') if File.directory?(config_file)
24
+ config_file ||= DEFAULT_CONFIG_FILE # if nil is passed
25
+ config_file = Pathname.new(config_file).expand_path
26
+ config_file += '.sundae' if config_file.directory?
25
27
 
26
- create_template_config_file(config_file) unless File.file?(config_file)
28
+ create_template_config_file(config_file) unless config_file.file?
27
29
 
28
30
  load(config_file)
29
- configatron.paths.map! { |p| File.expand_path(p) }
31
+ configatron.paths.map! { |p| Pathname.new(p).expand_path }
30
32
 
31
33
  # An array which lists the directories where mnts are stored.
32
34
  @paths = configatron.paths
@@ -39,13 +41,14 @@ module Sundae
39
41
  # asking the user.
40
42
  #
41
43
  def self.create_template_config_file(config_file)
44
+ config_file = Pathname.new(config_file).expand_path
42
45
  loop do
43
46
  print "#{config_file} does not exist. Create template there? (y/n): "
44
47
  ans = gets.downcase.strip
45
48
  if ans == "y" || ans == "yes"
46
49
  File.open(config_file, "w") do |f|
47
50
  f.puts <<-EOM.gsub(/^ {14}/, '')
48
- # -*-Ruby-*-
51
+ # -*-Ruby-*-
49
52
 
50
53
  # An array which lists the directories where mnts are stored.
51
54
  configatron.paths = ["~/mnt"]
@@ -76,13 +79,15 @@ module Sundae
76
79
  # ignored (i.e., no link will be made pointing to it).
77
80
  #
78
81
  def self.ignore_file?(file) # :doc:
79
- return true if File.basename(file) =~ /^\.\.?$/
80
- return true if File.basename(file) == ".sundae_path"
82
+ file = Pathname.new(file)
83
+ basename = file.basename.to_s
84
+ return true if basename =~ /^\.\.?$/
85
+ return true if basename == ".sundae_path"
81
86
  @ignore_rules.each do |r|
82
87
  if r.kind_of? Regexp
83
- return true if File.basename(file) =~ r
88
+ return true if basename =~ r
84
89
  else
85
- return true if File.fnmatch(r, file)
90
+ return true if file.fnmatch(r)
86
91
  end
87
92
  end
88
93
  return false
@@ -92,12 +97,19 @@ module Sundae
92
97
  # where in the file system links should be created for this mnt.
93
98
  #
94
99
  def self.install_location(mnt)
95
- mnt_config = File.join(mnt, '.sundae_path')
96
- if File.exist?(mnt_config)
97
- location = File.readlines(mnt_config)[0].strip
100
+ mnt = Pathname.new(mnt).expand_path
101
+ mnt_config = mnt + '.sundae_path'
102
+ if mnt_config.exist?
103
+ return Pathname.new(mnt_config.readlines[0].strip).expand_path
98
104
  end
99
105
 
100
- location ||= ENV['HOME']
106
+ base = mnt.basename.to_s
107
+ match = (/dot[-_](.*)/).match(base)
108
+ if match
109
+ return Pathname.new(Dir.home) + ('.' + match[1])
110
+ end
111
+
112
+ return Pathname.new(Dir.home)
101
113
  end
102
114
 
103
115
  # Return an array of all paths in the file system where links will
@@ -111,11 +123,12 @@ module Sundae
111
123
  # as an array.
112
124
  #
113
125
  def self.mnts_in_path(path)
126
+ Pathname.new(path).expand_path
114
127
  mnts = []
115
- collections = Dir.entries(path).delete_if {|a| a=~/^\./}
128
+ collections = path.children(false).delete_if {|c| c.to_s =~ /^\./}
116
129
  collections.each do |c|
117
- collection_mnts = Dir.entries(File.join(path, c)).delete_if {|a| a=~/^\./}
118
- collection_mnts.map! { |mnt| File.join(c, mnt) }
130
+ collection_mnts = (path + c).children(false).delete_if {|c| c.to_s =~ /^\./}
131
+ collection_mnts.map! { |mnt| (c + mnt) }
119
132
  mnts |= collection_mnts # |= is the union
120
133
  end
121
134
 
@@ -128,87 +141,109 @@ module Sundae
128
141
  mnts = []
129
142
 
130
143
  @paths.each do |path|
131
- next unless File.exist?(path)
132
- mnts |= mnts_in_path(path).map { |mnt| File.join(path, mnt) } # |= is the union operator
144
+ next unless path.exist?
145
+ mnts |= mnts_in_path(path).map { |mnt| path + mnt } # |= is the union operator
133
146
  end
134
-
135
147
  return mnts
136
148
  end
137
149
 
138
- # Return all subdirectories of the mnts returned by all_mnts. These
139
- # are the 'mirror' directories that are generated by sundae.
150
+ # Return all subdirectories and files in the mnts returned by
151
+ # all_mnts. These are the 'mirror' files and directories that are
152
+ # generated by sundae.
140
153
  #
141
- def self.generated_directories
154
+ def self.generated_files
142
155
  dirs = Array.new
143
156
 
144
157
  all_mnts.each do |mnt|
145
- mnt_dirs = Dir.entries(mnt).delete_if { |e| ignore_file?(e) }
158
+ mnt_dirs = mnt.children(false).delete_if { |e| ignore_file?(e) }
146
159
  mnt_dirs.each do |dir|
147
- dirs << File.join(install_location(mnt), dir)
160
+ dirs << (install_location(mnt) + dir)
148
161
  end
149
162
  end
150
163
 
151
- return dirs.sort.uniq.select { |d| File.directory?(d) }
164
+ return dirs.sort.uniq#.select { |d| d.directory? }
165
+ end
166
+
167
+ # Return all subdirectories of the mnts returned by all_mnts. These
168
+ # are the 'mirror' directories that are generated by sundae.
169
+ #
170
+ def self.generated_directories
171
+ generated_files.select {|f| f.directory?}
152
172
  end
153
173
 
154
174
  # Check for symlinks in the base directories that are missing their
155
175
  # targets.
156
176
  #
157
177
  def self.remove_dead_links
158
- removed_list = []
159
178
  install_locations.each do |location|
160
- next unless File.exist?(location)
161
- files = Dir.entries(location).map {|f| File.join(location, f)}
179
+ next unless location.exist?
180
+ files = location.entries.map { |f| location + f }
162
181
  files.each do |file|
163
- next unless File.symlink?(file)
164
- next if File.exist? File.readlink(file)
165
- FileUtils.rm(file)
166
- removed_list << file
182
+ next unless file.symlink?
183
+ next if file.readlink.exist?
184
+ next unless root_path(file.readlink)
185
+ file.delete
167
186
  end
168
187
  end
169
- return removed_list
170
188
  end
171
189
 
190
+ # Search through _directory_ and return the first static file found,
191
+ # nil otherwise.
192
+ #
193
+ def self.find_static_file(directory)
194
+ directory = Pathname.new(directory).expand_path
195
+
196
+ directory.find do |path|
197
+ return path if path.exist? && path.ftype == 'file'
198
+ end
199
+ return nil
200
+ end
201
+
172
202
  # Delete each generated directory if there aren't any real files in
173
203
  # them.
174
204
  #
175
205
  def self.remove_generated_directories
176
- removed_list = []
177
206
  generated_directories.each do |dir|
178
- next if File.basename(dir) == ('.sundae')
179
-
180
- # Do a search to make sure no non-symlink file is being
181
- # deleted. That would suck.
182
- if sf = find_static_file(dir)
183
- puts "found static file: #{sf}"
184
- else
185
- FileUtils.rmtree(dir)
186
- removed_list << dir
187
- end
207
+ # don't get rid of the linked config file
208
+ next if dir.basename.to_s == '.sundae'
209
+ remove_generated_stuff dir
210
+
211
+ # if sf = find_static_file(dir)
212
+ # puts "found static file: #{sf}"
213
+ # else
214
+ # dir.rmtree
215
+ # end
188
216
  end
189
- return removed_list
190
217
  end
191
218
 
192
- # Search through _directory_ and return the first static file found,
193
- # nil otherwise.
194
- #
195
- def self.find_static_file(directory)
196
- Find.find(directory) do |path|
197
- return path if File.exist?(path) && File.ftype(path) == 'file'
219
+ def self.remove_generated_files
220
+ generated_files.each do |fod|
221
+ # don't get rid of the linked config file
222
+ next if fod.basename.to_s == '.sundae'
223
+ remove_generated_stuff fod
198
224
  end
199
- return nil
200
225
  end
201
226
 
227
+ def self.remove_generated_stuff(fod)
228
+ return unless fod.exist?
229
+ if fod.ftype == 'directory'
230
+ fod.each_child do |c|
231
+ remove_generated_stuff c
232
+ end
233
+ fod.rmdir if fod.children.empty?
234
+ else
235
+ return unless fod.symlink?
236
+ fod.delete if root_path(fod.readlink) # try to only delete sundae links
237
+ end
238
+ end
239
+
202
240
  # Call minimally_create_links for each mnt.
203
241
  #
204
242
  def self.create_filesystem
205
- mnt_list = []
206
243
  all_mnts.each do |mnt|
207
- FileUtils.mkdir_p(File.expand_path(install_location(mnt)))
244
+ install_location(mnt).expand_path.mkpath
208
245
  minimally_create_links(mnt, install_location(mnt))
209
- mnt_list << mnt
210
246
  end
211
- return mnt_list
212
247
  end
213
248
 
214
249
  # For each directory and file in _target_, create a link at <em>link_name</em>. If
@@ -240,11 +275,15 @@ module Sundae
240
275
  # Starting at _dir_, walk up the directory hierarchy and return the
241
276
  # directory that is contained in _@paths_.
242
277
  #
243
- def self.root_path(dir)
244
- raise ArgumentError if dir == '/'
278
+ def self.root_path(path)
279
+ path = Pathname.new(path).expand_path
280
+ last = path
281
+ path.ascend do |v|
282
+ return last if @paths.include? v
283
+ last = v
284
+ end
245
285
 
246
- parent = File.expand_path(File.join(dir, '..'))
247
- return (@paths.include?(parent)) ? dir : root_path(parent)
286
+ return nil
248
287
  end
249
288
 
250
289
  # Dispatch calls to create_directory_link and create_file_link.
@@ -266,7 +305,7 @@ module Sundae
266
305
  def self.create_file_link(target, link_name)
267
306
  raise ArgumentError, "#{target} does not exist" unless File.file?(target)
268
307
  if File.exist?(link_name)
269
- raise ArgumentError, "#{link_name} cannot be overwritten" unless File.symlink?(link_name)
308
+ raise ArgumentError, "#{link_name} cannot be overwritten for #{target}." unless File.symlink?(link_name)
270
309
  if (not File.exist?(File.readlink(link_name)))
271
310
  FileUtils.ln_sf(target, link_name)
272
311
  else
@@ -285,18 +324,19 @@ module Sundae
285
324
  #
286
325
  def self.create_directory_link(target, link_name)
287
326
  raise ArgumentError unless File.directory?(target)
288
- if (not File.exist?(link_name)) || (File.symlink?(link_name) && (not File.exist?(File.readlink(link_name))))
327
+ if (not File.exist?(link_name)) ||
328
+ (File.symlink?(link_name) && (not File.exist?(File.readlink(link_name))))
289
329
  FileUtils.ln_sf(target, link_name)
290
330
  else
291
331
  case File.ftype(link_name)
292
332
  when 'file'
293
- raise "Could not link #{target} to #{link_name}"
333
+ raise "Could not link #{link_name} to #{target}: target exists."
294
334
  when 'directory'
295
335
  minimally_create_links(target, link_name)
296
336
  when 'link'
297
337
  case File.ftype(File.readlink(link_name))
298
338
  when 'file'
299
- raise "Could not link #{target} to #{link_name}"
339
+ raise "Could not link #{link_name} to #{target}: another link exists there."
300
340
  when 'directory'
301
341
  combine_directories(link_name, target, File.readlink(link_name))
302
342
  end
@@ -308,6 +348,7 @@ module Sundae
308
348
  # <em>target_path1</em> and <em>target_path2</em>.
309
349
  #
310
350
  def self.combine_directories(link_name, target_path1, target_path2)
351
+ raise unless File.symlink?(link_name)
311
352
  return if target_path1 == target_path2
312
353
 
313
354
  FileUtils.rm(link_name)
@@ -318,13 +359,13 @@ module Sundae
318
359
 
319
360
  def self.update_filesystem
320
361
  remove_dead_links
321
- remove_generated_directories
362
+ remove_generated_files
322
363
  create_filesystem
323
364
  end
324
365
 
325
366
  def self.remove_filesystem
326
367
  remove_dead_links
327
- remove_generated_directories
368
+ remove_generated_files
328
369
  end
329
370
 
330
371
  # Return an array of mnts that are installing to +path+.
data/test/test_sundae.rb CHANGED
@@ -3,41 +3,34 @@ require 'test/unit'
3
3
  $:.unshift File.join(File.dirname(__FILE__), "..", "bin") # add ../bin to the Ruby library path
4
4
  $:.unshift File.join(File.dirname(__FILE__), "..", "lib") # ../lib
5
5
  require 'sundae'
6
+ require 'pathname'
6
7
 
7
8
  class TestSundae < Test::Unit::TestCase
8
9
 
9
- @@testdir = File.dirname(File.expand_path(__FILE__))
10
- @@sandbox = File.join(@@testdir, 'sandbox')
11
- @@static_dir = File.join(@@sandbox, 'static')
12
- @@mnts_dir = File.join(@@sandbox, 'mnts')
10
+ @@testdir = Pathname.new(__FILE__).parent.expand_path
11
+ @@sandbox = @@testdir + 'sandbox'
12
+ @@static_dir = @@sandbox + 'static'
13
+ @@mnts_dir = @@sandbox + 'mnts'
13
14
 
14
15
  def setup
15
- FileUtils.mkdir_p(@@sandbox)
16
-
17
- FileUtils.mkdir_p(@@static_dir)
18
- File.open(File.join(@@static_dir, 'static'), 'w')
19
- FileUtils.mkdir_p(File.join(@@mnts_dir, 'c1'))
20
- FileUtils.mkdir_p(File.join(@@mnts_dir, 'c2'))
21
- FileUtils.mkdir_p(File.join(@@mnts_dir, 'c1/d1'))
22
- FileUtils.mkdir_p(File.join(@@mnts_dir, 'c1/d2'))
23
- FileUtils.mkdir_p(File.join(@@mnts_dir, 'c2/d1'))
24
- FileUtils.mkdir_p(File.join(@@mnts_dir, 'c2/d3'))
25
- FileUtils.mkdir_p(File.join(@@mnts_dir, 'c2/d3/d31'))
26
- File.open(File.join(@@mnts_dir, 'c1/d1/f11'), 'w')
27
- File.open(File.join(@@mnts_dir, 'c1/d1/f12'), 'w')
28
- File.open(File.join(@@mnts_dir, 'c1/d2/f21'), 'w')
29
- File.open(File.join(@@mnts_dir, 'c2/d1/f13'), 'w')
30
- File.open(File.join(@@mnts_dir, 'c2/d1/f14'), 'w')
31
- File.open(File.join(@@mnts_dir, 'c2/d3/f31'), 'w')
32
- ['c1/d1', 'c1/d2', 'c2/d1', 'c2/d3'].each do |d|
33
- File.open(File.join(@@mnts_dir, d, '.sundae_path'), 'w') do |f|
34
- f.puts @@sandbox
35
- end
16
+ @@sandbox.mkpath
17
+ @@static_dir.mkpath
18
+
19
+ (@@static_dir + 'static').open('w')
20
+ %w(c1 c2 c1/d1 c1/d2 c2/d1 c2/d3 c2/d3/d31).each do |x|
21
+ (@@mnts_dir + x).mkpath
22
+ end
23
+
24
+ %w(c1/d1/f11 c1/d1/f12 c1/d2/f21 c2/d1/f13 c2/d1/f14 c2/d3/f31).each do |x|
25
+ (@@mnts_dir + x).open('w')
36
26
  end
37
27
 
38
- @@path1 = File.join(@@sandbox, 'mnts')
28
+ %w(c1/d1 c1/d2 c2/d1 c2/d3).each do |d|
29
+ (@@mnts_dir + d + '.sundae_path').open('w') {|f| f.puts @@sandbox}
30
+ end
39
31
 
40
- @@config_file = File.join(@@sandbox, ".sundae")
32
+ @@path1 = @@sandbox + 'mnts'
33
+ @@config_file = @@sandbox + '.sundae'
41
34
  File.open(@@config_file, 'w+') do |f|
42
35
  f.puts "configatron.paths = [\"#{@@path1}\"]"
43
36
  f.puts "configatron.ignore_rules = %w("
@@ -49,24 +42,24 @@ class TestSundae < Test::Unit::TestCase
49
42
  end
50
43
 
51
44
  def teardown
52
- FileUtils.rm_r(@@sandbox)
45
+ @@sandbox.rmtree
53
46
  end
54
47
 
55
48
  def test_class_all_mnts
56
49
  all_mnts = Sundae.all_mnts
57
50
  mnts = Sundae.mnts_in_path(@@path1)
58
51
  mnts.each do |m|
59
- assert all_mnts.include?(File.join(@@path1,m))
52
+ assert all_mnts.include?(@@path1 + m)
60
53
  end
61
54
  end
62
55
 
63
56
  def test_class_combine_directories
64
- d1 = File.join(@@mnts_dir, 'c1/d1')
65
- d2 = File.join(@@mnts_dir, 'c1/d2')
66
- link = File.join(@@sandbox, 'link')
57
+ d1 = @@mnts_dir + 'c1/d1'
58
+ d2 = @@mnts_dir + 'c1/d2'
59
+ link = @@sandbox + 'link'
67
60
  FileUtils.ln_s(d1, link)
68
61
  Sundae.combine_directories(link, d1, d2)
69
- assert File.symlink?(File.join(link, 'f11'))
62
+ assert File.symlink?(link + 'f11')
70
63
  end
71
64
 
72
65
  def test_class_create_directory_link
@@ -125,6 +118,12 @@ class TestSundae < Test::Unit::TestCase
125
118
  assert_equal 1, Sundae.generated_directories.size
126
119
  end
127
120
 
121
+ def test_class_generated_files
122
+ Sundae.create_filesystem
123
+ # assert Sundae.generated_files.include?(File.join(@@sandbox, 'f11'))
124
+ assert_equal 7, Sundae.generated_files.size
125
+ end
126
+
128
127
  def test_class_ignore_file_eh
129
128
  assert Sundae.ignore_file?('.sundae_path')
130
129
  assert Sundae.ignore_file?('..')
@@ -135,45 +134,45 @@ class TestSundae < Test::Unit::TestCase
135
134
  end
136
135
 
137
136
  def test_class_install_location
138
- assert_equal Sundae.install_location('/'), ENV['HOME']
139
- assert_equal Sundae.install_location(File.join(@@mnts_dir, 'c1/d1')), @@sandbox
137
+ assert_equal Pathname.new(Dir.home), Sundae.install_location('/')
138
+ assert_equal @@sandbox, Sundae.install_location(@@mnts_dir + 'c1/d1')
140
139
  end
141
140
 
142
141
  def test_class_install_locations
143
- assert_equal Sundae.install_locations, [@@sandbox]
142
+ assert_equal [@@sandbox], Sundae.install_locations
144
143
  end
145
144
 
146
145
  def test_class_load_config_file
147
146
  sundae_paths = Sundae.instance_variable_get(:@paths)
148
- assert_equal sundae_paths[0], File.expand_path(@@path1)
147
+ assert_equal sundae_paths[0], Pathname.new(@@path1).expand_path
149
148
  end
150
149
 
151
150
  def test_class_minimally_create_links
152
151
  c1 = File.join(@@mnts_dir, 'c1')
153
152
  c2 = File.join(@@mnts_dir, 'c2')
154
153
  Sundae.minimally_create_links(c1, @@sandbox)
155
- assert File.symlink?(File.join(@@sandbox, 'd1'))
156
- assert File.symlink?(File.join(@@sandbox, 'd2'))
154
+ assert((@@sandbox + 'd1').symlink?)
155
+ assert((@@sandbox + 'd2').symlink?)
157
156
  Sundae.minimally_create_links(c2, @@sandbox)
158
- assert File.directory?(File.join(@@sandbox, 'd1'))
159
- assert File.symlink?(File.join(@@sandbox, 'd1/f11'))
160
- assert File.symlink?(File.join(@@sandbox, 'd1/f14'))
161
- assert File.symlink?(File.join(@@sandbox, 'd2'))
162
- assert File.symlink?(File.join(@@sandbox, 'd3'))
157
+ assert((@@sandbox + 'd1').directory?)
158
+ assert((@@sandbox + 'd1/f11').symlink?)
159
+ assert((@@sandbox + 'd1/f14').symlink?)
160
+ assert((@@sandbox + 'd2').symlink?)
161
+ assert((@@sandbox + 'd3').symlink?)
163
162
  end
164
163
 
165
164
  def test_class_mnts_in_path
166
- assert_equal Sundae.mnts_in_path(@@path1), ['c1/d1', 'c1/d2', 'c2/d1', 'c2/d3']
165
+ assert_equal ['c1/d1', 'c1/d2', 'c2/d1', 'c2/d3'].map {|x| Pathname.new(x)},
166
+ Sundae.mnts_in_path(@@path1)
167
167
  end
168
168
 
169
169
  def test_class_remove_dead_links
170
- File.open(File.join(@@sandbox, 'temp_file'), 'w')
171
- File.open(File.join(@@sandbox, 'perm_file'), 'w')
170
+ (@@sandbox + 'temp_file').open('w')
171
+ (@@sandbox + 'perm_file').open('w')
172
172
  FileUtils.ln_s(File.join(@@sandbox, 'temp_file'), File.join(@@sandbox, 'link'))
173
- FileUtils.rm(File.join(@@sandbox, 'temp_file'))
174
- assert_equal Sundae.remove_dead_links, [File.join(@@sandbox, 'link')]
175
- assert ! File.exist?(File.join(@@sandbox, 'link'))
176
- assert File.exist?(File.join(@@sandbox, 'perm_file'))
173
+ (@@sandbox + 'temp_file').delete
174
+ assert ! (@@sandbox + 'link').exist?
175
+ assert (@@sandbox + 'perm_file').exist?
177
176
  end
178
177
 
179
178
  def test_class_remove_generated_directories
@@ -185,12 +184,9 @@ class TestSundae < Test::Unit::TestCase
185
184
  end
186
185
 
187
186
  def test_class_root_path
188
- assert_equal Sundae.root_path(File.join(@@mnts_dir, 'c1')), File.join(@@mnts_dir, 'c1')
189
- assert_equal Sundae.root_path(File.join(@@mnts_dir, 'c1/d1')), File.join(@@mnts_dir, 'c1')
190
-
191
- assert_raise ArgumentError do
192
- Sundae.root_path('/')
193
- end
187
+ assert_equal @@mnts_dir +'c1', Sundae.root_path(@@mnts_dir + 'c1')
188
+ assert_equal @@mnts_dir + 'c1', Sundae.root_path(@@mnts_dir + 'c1/d1')
189
+ assert_equal nil, Sundae.root_path('/')
194
190
  end
195
191
 
196
192
  def test_class_create_link
data/unison/common ADDED
@@ -0,0 +1,17 @@
1
+ fastcheck = true
2
+
3
+ # Roots of the synchronization
4
+ include local_mnt_path
5
+
6
+ ui = text
7
+ log = false
8
+ auto = true
9
+
10
+ # Names and paths to ignore:
11
+ ignore = Name temp.*
12
+ ignore = Name *~
13
+ ignore = Name .*~
14
+ ignore = Name *.o
15
+ ignore = Name *.tmp
16
+ ignore = Name .emacs_autosaves
17
+ ignore = Name .emacs_backups
@@ -0,0 +1,12 @@
1
+ include common
2
+
3
+ root = ssh://donmarch.org//home/14129/users/don%donmarch.org/var/unison/mnts
4
+ sshargs = "-l don%donmarch.org"
5
+
6
+ path = linux
7
+ path = nix
8
+ path = personal
9
+ path = personal_private
10
+ path = proprietorship
11
+ path = personal_archive
12
+ path = reference
data/version.txt CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.0.2
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sundae
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-27 00:00:00.000000000 Z
12
+ date: 2012-02-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: highline
16
- requirement: &74378590 !ruby/object:Gem::Requirement
16
+ requirement: &79306580 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.6.11
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *74378590
24
+ version_requirements: *79306580
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: configatron
27
- requirement: &74378180 !ruby/object:Gem::Requirement
27
+ requirement: &79306020 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 2.9.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *74378180
35
+ version_requirements: *79306020
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rdoc
38
- requirement: &74377570 !ruby/object:Gem::Requirement
38
+ requirement: &79305190 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '3.12'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *74377570
46
+ version_requirements: *79305190
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bones
49
- requirement: &74376910 !ruby/object:Gem::Requirement
49
+ requirement: &79303240 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: 3.7.3
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *74376910
57
+ version_requirements: *79303240
58
58
  description: Mix collections of files while maintaining complete separation.
59
59
  email: don@ohspite.net
60
60
  executables:
@@ -67,6 +67,8 @@ extra_rdoc_files:
67
67
  - !binary |-
68
68
  YmluL3N1bmRhZQ==
69
69
  files:
70
+ - !binary |-
71
+ LmdpdGlnbm9yZQ==
70
72
  - !binary |-
71
73
  Q0hBTkdFTE9H
72
74
  - !binary |-
@@ -81,6 +83,10 @@ files:
81
83
  bGliL3N1bmRhZS5yYg==
82
84
  - !binary |-
83
85
  dGVzdC90ZXN0X3N1bmRhZS5yYg==
86
+ - !binary |-
87
+ dW5pc29uL2NvbW1vbg==
88
+ - !binary |-
89
+ dW5pc29uL210X2V4YW1wbGUucHJm
84
90
  - !binary |-
85
91
  dmVyc2lvbi50eHQ=
86
92
  homepage: https://github.com/ohspite/sundae