properly handle the case where we generate the same name than an already existing...
authorLunar <lunar@anargeek.net>
Tue, 6 Mar 2012 15:23:11 +0000 (16:23 +0100)
committerLunar <lunar@anargeek.net>
Fri, 23 Mar 2012 17:11:29 +0000 (18:11 +0100)
lib/coquelicot/depot.rb
spec/coquelicot/depot_spec.rb

index 5d37d93..38aa7f8 100644 (file)
@@ -39,20 +39,28 @@ module Coquelicot
           next # let's try again
         end
       end
-      link = gen_random_file_name
-      add_link(link, dst)
-      link
+
+      # retry to add the link until a free name is generated
+      loop do
+        link = gen_random_file_name
+        return link if add_link(link, dst)
+      end
     end
 
     def get_file(link, pass=nil)
-      name = read_link(link)
+      name = nil
+      lockfile.lock do
+        name = read_link(link)
+      end
       return nil if name.nil?
       StoredFile::open(full_path(name), pass)
     end
 
     def file_exists?(link)
-      name = read_link(link)
-      return !name.nil?
+      lockfile.lock do
+        name = read_link(link)
+        return !name.nil?
+      end
     end
 
     def gc!
@@ -90,10 +98,13 @@ module Coquelicot
 
     def add_link(src, dst)
       lockfile.lock do
+        return false unless read_link(src).nil?
+
         File.open(links_path, 'a') do |f|
           f.write("#{src} #{dst}\n")
         end
       end
+      true
     end
 
     def remove_from_links(&block)
@@ -116,17 +127,15 @@ module Coquelicot
 
     def read_link(src)
       dst = nil
-      lockfile.lock do
-        File.open(links_path) do |f|
-          begin
-            line = f.readline rescue break
-            if line.start_with? "#{src} " then
-              dst = line.split[1]
-              break
-            end
-          end until line.empty?
-        end if File.exists?(links_path)
-      end
+      File.open(links_path) do |f|
+        begin
+          line = f.readline rescue break
+          if line.start_with? "#{src} " then
+            dst = line.split[1]
+            break
+          end
+        end until line.empty?
+      end if File.exists?(links_path)
       dst
     end
 
index 18d5725..d9e7a8e 100644 (file)
@@ -110,7 +110,20 @@ module Coquelicot
           File.read(File.expand_path('.links', @tmpdir)).should =~ /^link\s+file$/
         end
         context 'when it generates a link name that is already taken' do
-          it 'should find another name'
+          before(:each) do
+            depot.stub(:gen_random_file_name).
+              and_return('file', 'link', 'another', 'link', 'another_link')
+            # add 'link' pointing to 'file'
+            add_file
+            # now it should add 'another_link' -> 'another'
+            @link = add_file
+          end
+          it 'should not overwrite the existing link' do
+            depot.size.should == 2
+          end
+          it 'should find another name' do
+            @link.should == 'another_link'
+          end
         end
       end
     end