diff options
-rw-r--r-- | lib/puppet/type/file.rb | 22 | ||||
-rwxr-xr-x | spec/unit/type/file.rb | 134 |
2 files changed, 136 insertions, 20 deletions
diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb index 51865ef49..6d71abce0 100644 --- a/lib/puppet/type/file.rb +++ b/lib/puppet/type/file.rb @@ -29,8 +29,8 @@ Puppet::Type.newtype(:file) do isnamevar validate do |value| - # use underlying platform's convention to check for relative paths - unless File.expand_path(value) == value + # accept various path syntaxes: lone slash, posix, win32, unc + unless value =~ /^\/$/ or value =~ /^\/[^\/]/ or value =~ /^.:\// or value =~ /^\/\/[^\/]+\/[^\/]+/ fail Puppet::Error,"File paths must be fully qualified, not '#{value}'" end end @@ -44,13 +44,23 @@ Puppet::Type.newtype(:file) do # and the reverse unmunge do |value| - File.join( Puppet::FileCollection.collection.path(value[:index]), value[:name] ) + basedir = Puppet::FileCollection.collection.path(value[:index]) + # a lone slash as :name indicates a root dir on windows + if value[:name] == '/' + basedir + else + File.join( basedir, value[:name] ) + end end to_canonicalize do |s| - # Get rid of any duplicate slashes, and remove any trailing slashes unless - # the title is just a slash, in which case leave it. - s.gsub(/\/+/, "/").sub(/(.)\/$/,'\1') + # * if it looks like a windows path, replace all backslashes with forward slashes + # * get rid of any duplicate slashes + # * remove any trailing slashes unless the title is just a slash, or a + # drive letter in which case leave it + # * UNCs in the form //server//share/... keep their initial double slash. + s = s.gsub(/\\/, '/') if s =~ /^.:\/\\/ or s =~ /^\/\/[^\/]+\/[^\/]+/ + s.gsub(/(.)\/+/, '\1/').sub(/([^:])\/$/,'\1') end end diff --git a/spec/unit/type/file.rb b/spec/unit/type/file.rb index 4213753a4..4ce627549 100755 --- a/spec/unit/type/file.rb +++ b/spec/unit/type/file.rb @@ -150,24 +150,130 @@ describe Puppet::Type.type(:file) do @file.must_not be_should_be_file end - it "should autorequire its parent directory" do - catalog = Puppet::Resource::Catalog.new - file = Puppet::Type::File.new(:name => "/foo/bar") - dir = Puppet::Type::File.new(:name => "/foo") - catalog.add_resource file - catalog.add_resource dir - reqs = file.autorequire - reqs[0].source.must == dir - reqs[0].target.must == file + describe "when using POSIX filenames" do + it "should autorequire its parent directory" do + file = Puppet::Type::File.new(:path => "/foo/bar") + dir = Puppet::Type::File.new(:path => "/foo") + @catalog.add_resource file + @catalog.add_resource dir + reqs = file.autorequire + reqs[0].source.must == dir + reqs[0].target.must == file + end + + it "should not autorequire its parent dir if its parent dir is itself" do + file = Puppet::Type::File.new(:path => "/") + @catalog.add_resource file + file.autorequire.should be_empty + end + + it "should remove trailing slashes" do + file = Puppet::Type::File.new(:path => "/foo/bar/baz/") + file[:path].should == "/foo/bar/baz" + end + + it "should remove double slashes" do + file = Puppet::Type::File.new(:path => "/foo/bar//baz") + file[:path].should == "/foo/bar/baz" + end + + it "should remove trailing double slashes" do + file = Puppet::Type::File.new(:path => "/foo/bar/baz//") + file[:path].should == "/foo/bar/baz" + end + + it "should leave a single slash alone" do + file = Puppet::Type::File.new(:path => "/") + file[:path].should == "/" + end end - it "should not autorequire its parent dir if its parent dir is itself" do - catalog = Puppet::Resource::Catalog.new - file = Puppet::Type::File.new(:name => "/") - catalog.add_resource file - file.autorequire.should be_empty + describe "when using Win32 filenames" do + it "should autorequire its parent directory" do + file = Puppet::Type::File.new(:path => "X:/foo/bar") + dir = Puppet::Type::File.new(:path => "X:/foo") + @catalog.add_resource file + @catalog.add_resource dir + reqs = file.autorequire + reqs[0].source.must == dir + reqs[0].target.must == file + end + + it "should not autorequire its parent dir if its parent dir is itself" do + file = Puppet::Type::File.new(:path => "X:/") + @catalog.add_resource file + file.autorequire.should be_empty + end + + it "should remove trailing slashes" do + file = Puppet::Type::File.new(:path => "X:/foo/bar/baz/") + file[:path].should == "X:/foo/bar/baz" + end + + it "should remove double slashes" do + file = Puppet::Type::File.new(:path => "X:/foo/bar//baz") + file[:path].should == "X:/foo/bar/baz" + end + + it "should remove trailing double slashes" do + file = Puppet::Type::File.new(:path => "X:/foo/bar/baz//") + file[:path].should == "X:/foo/bar/baz" + end + + it "should leave a drive letter with a slash alone" do + file = Puppet::Type::File.new(:path => "X:/") + file[:path].should == "X:/" + end + + it "should add a slash to a drive letter" do + file = Puppet::Type::File.new(:path => "X:") + file[:path].should == "X:/" + end end + describe "when using UNC filenames" do + it "should autorequire its parent directory" do + file = Puppet::Type::File.new(:path => "//server/foo/bar") + dir = Puppet::Type::File.new(:path => "//server/foo") + @catalog.add_resource file + @catalog.add_resource dir + reqs = file.autorequire + reqs[0].source.must == dir + reqs[0].target.must == file + end + + it "should not autorequire its parent dir if its parent dir is itself" do + file = Puppet::Type::File.new(:path => "//server/foo") + @catalog.add_resource file + puts file.autorequire + file.autorequire.should be_empty + end + + it "should remove trailing slashes" do + file = Puppet::Type::File.new(:path => "//server/foo/bar/baz/") + file[:path].should == "//server/foo/bar/baz" + end + + it "should remove double slashes" do + file = Puppet::Type::File.new(:path => "//server/foo/bar//baz") + file[:path].should == "//server/foo/bar/baz" + end + + it "should remove trailing double slashes" do + file = Puppet::Type::File.new(:path => "//server/foo/bar/baz//") + file[:path].should == "//server/foo/bar/baz" + end + + it "should remove a trailing slash from a sharename" do + file = Puppet::Type::File.new(:path => "//server/foo/") + file[:path].should == "//server/foo" + end + + it "should not modify a sharename" do + file = Puppet::Type::File.new(:path => "//server/foo") + file[:path].should == "//server/foo" + end + end describe "when initializing" do it "should set a desired 'ensure' value if none is set and 'content' is set" do |