diff --git a/lib/puppet/parser/files.rb b/lib/puppet/parser/files.rb index 035b21a8c..30e92dc60 100644 --- a/lib/puppet/parser/files.rb +++ b/lib/puppet/parser/files.rb @@ -1,133 +1,99 @@ module Puppet::Parser::Files module_function # Return a list of manifests as absolute filenames matching the given # pattern. # # @param pattern [String] A reference for a file in a module. It is the # format "/" # @param environment [Puppet::Node::Environment] the environment of modules # # @return [Array(String, Array)] the module name and the list of files found # @api private def find_manifests_in_modules(pattern, environment) module_name, file_pattern = split_file_path(pattern) if mod = environment.module(module_name) [mod.name, mod.match_manifests(file_pattern)] else [nil, []] end end # Find the path to the given file selector. Files can be selected in # one of two ways: # * absolute path: the path is simply returned # * modulename/filename selector: a file is found in the file directory # of the named module. # # In the second case a nil is returned if there isn't a file found. In the # first case (absolute path), there is no existence check done and so the # path will be returned even if there isn't a file available. # # @param template [String] the file selector # @param environment [Puppet::Node::Environment] the environment in which to search # @return [String, nil] the absolute path to the file or nil if there is no file found # # @api private def find_file(file, environment) if Puppet::Util.absolute_path?(file) file else path, module_file = split_file_path(file) mod = environment.module(path) if module_file && mod mod.file(module_file) else nil end end end # Find the path to the given template selector. Templates can be selected in - # a number of ways: + # a couple of ways: # * absolute path: the path is simply returned - # * path relative to the templatepath setting: a file is found and the path - # is returned # * modulename/filename selector: a file is found in the template directory # of the named module. # # In the last two cases a nil is returned if there isn't a file found. In the # first case (absolute path), there is no existence check done and so the # path will be returned even if there isn't a file available. # # @param template [String] the template selector # @param environment [Puppet::Node::Environment] the environment in which to search # @return [String, nil] the absolute path to the template file or nil if there is no file found # # @api private def find_template(template, environment) if Puppet::Util.absolute_path?(template) template else - in_templatepath = find_template_in_templatepath(template, environment) - if in_templatepath - in_templatepath - else - find_template_in_module(template, environment) - end - end - end - - # Templatepaths are deprecated functionality, this will be going away in - # Puppet 4. - # - # @api private - def find_template_in_templatepath(template, environment) - template_paths = templatepath(environment) - if template_paths - template_paths.collect do |path| - File::join(path, template) - end.find do |f| - Puppet::FileSystem.exist?(f) - end - else - nil + find_template_in_module(template, environment) end end # @api private def find_template_in_module(template, environment) path, file = split_file_path(template) mod = environment.module(path) if file && mod mod.template(file) else nil end end - # Return an array of paths by splitting the +templatedir+ config - # parameter. - # @api private - def templatepath(environment) - dirs = Puppet.settings.value(:templatedir, environment.to_s).split(File::PATH_SEPARATOR) - dirs.select do |p| - File::directory?(p) - end - end - # Split the path into the module and the rest of the path, or return # nil if the path is empty or absolute (starts with a /). # @api private def split_file_path(path) if path == "" || Puppet::Util.absolute_path?(path) nil else path.split(File::SEPARATOR, 2) end end end diff --git a/spec/unit/parser/files_spec.rb b/spec/unit/parser/files_spec.rb index 5df46d978..2c97a735c 100755 --- a/spec/unit/parser/files_spec.rb +++ b/spec/unit/parser/files_spec.rb @@ -1,157 +1,102 @@ #! /usr/bin/env ruby require 'spec_helper' require 'puppet/parser/files' describe Puppet::Parser::Files do include PuppetSpec::Files - let(:environment) { Puppet::Node::Environment.create(:testing, []) } + let(:modulepath) { tmpdir("modulepath") } + let(:environment) { Puppet::Node::Environment.create(:testing, [modulepath]) } + let(:mymod) { File.join(modulepath, "mymod") } + let(:mymod_files) { File.join(mymod, "files") } + let(:mymod_a_file) { File.join(mymod_files, "some.txt") } + let(:mymod_templates) { File.join(mymod, "templates") } + let(:mymod_a_template) { File.join(mymod_templates, "some.erb") } + let(:mymod_manifests) { File.join(mymod, "manifests") } + let(:mymod_init_manifest) { File.join(mymod_manifests, "init.pp") } + let(:mymod_another_manifest) { File.join(mymod_manifests, "another.pp") } + let(:an_absolute_file_path_outside_of_module) { make_absolute("afilenamesomewhere") } before do - @basepath = make_absolute("/somepath") - end - - describe "when searching for files" do - it "should return fully-qualified files directly" do - Puppet::Parser::Files.expects(:modulepath).never - Puppet::Parser::Files.find_file(@basepath + "/my/file", environment).should == @basepath + "/my/file" - end - - it "should return the first found file" do - mod = mock 'module' - mod.expects(:file).returns("/one/mymod/files/myfile") - environment.expects(:module).with("mymod").returns mod - - Puppet::Parser::Files.find_file("mymod/myfile", environment).should == "/one/mymod/files/myfile" - end - - it "should return nil if template is not found" do - Puppet::Parser::Files.find_file("foomod/myfile", environment).should be_nil - end - end - - describe "when searching for templates" do - it "should return fully-qualified templates directly" do - Puppet::Parser::Files.expects(:modulepath).never - Puppet::Parser::Files.find_template(@basepath + "/my/template", environment).should == @basepath + "/my/template" - end - - it "should return the template from the first found module" do - mod = mock 'module' - mod.expects(:template).returns("/one/mymod/templates/mytemplate") - environment.expects(:module).with("mymod").returns mod - - Puppet::Parser::Files.find_template("mymod/mytemplate", environment).should == "/one/mymod/templates/mytemplate" + FileUtils.mkdir_p(mymod_files) + File.open(mymod_a_file, 'w') do |f| + f.puts('something') end - - it "should return the file in the templatedir if it exists" do - Puppet[:templatedir] = "/my/templates" - Puppet[:modulepath] = "/one:/two" - File.stubs(:directory?).returns(true) - Puppet::FileSystem.stubs(:exist?).returns(true) - Puppet::Parser::Files.find_template("mymod/mytemplate", environment).should == File.join(Puppet[:templatedir], "mymod/mytemplate") - end - - it "should not raise an error if no valid templatedir exists and the template exists in a module" do - mod = mock 'module' - mod.expects(:template).returns("/one/mymod/templates/mytemplate") - environment.expects(:module).with("mymod").returns mod - Puppet::Parser::Files.stubs(:templatepath).with(environment).returns(nil) - - Puppet::Parser::Files.find_template("mymod/mytemplate", environment).should == "/one/mymod/templates/mytemplate" + FileUtils.mkdir_p(mymod_templates) + File.open(mymod_a_template, 'w') do |f| + f.puts('<%= "something" %>') end - - it "should return unqualified templates if they exist in the template dir" do - Puppet::FileSystem.stubs(:exist?).returns true - Puppet::Parser::Files.stubs(:templatepath).with(environment).returns(["/my/templates"]) - - Puppet::Parser::Files.find_template("mytemplate", environment).should == "/my/templates/mytemplate" + FileUtils.mkdir_p(mymod_manifests) + File.open(mymod_init_manifest, 'w') do |f| + f.puts('class mymod { }') end - - it "should only return templates if they actually exist" do - Puppet::FileSystem.expects(:exist?).with("/my/templates/mytemplate").returns true - Puppet::Parser::Files.stubs(:templatepath).with(environment).returns(["/my/templates"]) - Puppet::Parser::Files.find_template("mytemplate", environment).should == "/my/templates/mytemplate" + File.open(mymod_another_manifest, 'w') do |f| + f.puts('class mymod::another { }') end + end - it "should return nil when asked for a template that doesn't exist" do - Puppet::FileSystem.expects(:exist?).with("/my/templates/mytemplate").returns false - Puppet::Parser::Files.stubs(:templatepath).with(environment).returns(["/my/templates"]) - Puppet::Parser::Files.find_template("mytemplate", environment).should be_nil + describe "when searching for files" do + it "returns fully-qualified file names directly" do + expect(Puppet::Parser::Files.find_file(an_absolute_file_path_outside_of_module, environment)).to eq(an_absolute_file_path_outside_of_module) end - it "should accept relative templatedirs" do - Puppet::FileSystem.stubs(:exist?).returns true - Puppet[:templatedir] = "my/templates" - File.expects(:directory?).with(File.expand_path("my/templates")).returns(true) - Puppet::Parser::Files.find_template("mytemplate", environment).should == File.expand_path("my/templates/mytemplate") + it "returns the full path to the file if given a modulename/relative_filepath selector " do + expect(Puppet::Parser::Files.find_file("mymod/some.txt", environment)).to eq(mymod_a_file) end - it "should use the environment templatedir if no module is found and an environment is specified" do - Puppet::FileSystem.stubs(:exist?).returns true - Puppet::Parser::Files.stubs(:templatepath).with(environment).returns(["/myenv/templates"]) - Puppet::Parser::Files.find_template("mymod/mytemplate", environment).should == "/myenv/templates/mymod/mytemplate" + it "returns nil if the module is not found" do + expect(Puppet::Parser::Files.find_file("mod_does_not_exist/myfile", environment)).to be_nil end - it "should use first dir from environment templatedir if no module is found and an environment is specified" do - Puppet::FileSystem.stubs(:exist?).returns true - Puppet::Parser::Files.stubs(:templatepath).with(environment).returns(["/myenv/templates", "/two/templates"]) - Puppet::Parser::Files.find_template("mymod/mytemplate", environment).should == "/myenv/templates/mymod/mytemplate" + it "also returns nil if the module is found, but the file is not" do + expect(Puppet::Parser::Files.find_file("mymod/file_does_not_exist", environment)).to be_nil end + end - it "should use a valid dir when templatedir is a path for unqualified templates and the first dir contains template" do - Puppet::Parser::Files.stubs(:templatepath).returns(["/one/templates", "/two/templates"]) - Puppet::FileSystem.expects(:exist?).with("/one/templates/mytemplate").returns(true) - Puppet::Parser::Files.find_template("mytemplate", environment).should == "/one/templates/mytemplate" + describe "when searching for templates" do + it "returns fully-qualified templates directly" do + expect(Puppet::Parser::Files.find_template(an_absolute_file_path_outside_of_module, environment)).to eq(an_absolute_file_path_outside_of_module) end - it "should use a valid dir when templatedir is a path for unqualified templates and only second dir contains template" do - Puppet::Parser::Files.stubs(:templatepath).returns(["/one/templates", "/two/templates"]) - Puppet::FileSystem.expects(:exist?).with("/one/templates/mytemplate").returns(false) - Puppet::FileSystem.expects(:exist?).with("/two/templates/mytemplate").returns(true) - Puppet::Parser::Files.find_template("mytemplate", environment).should == "/two/templates/mytemplate" + it "returns the full path to the template if given a modulename/relative_templatepath selector" do + expect(Puppet::Parser::Files.find_template("mymod/some.erb", environment)).to eq(mymod_a_template) end - it "should use the node environment if specified" do - mod = mock 'module' - environment.expects(:module).with("mymod").returns mod - - mod.expects(:template).returns("/my/modules/mymod/templates/envtemplate") - - Puppet::Parser::Files.find_template("mymod/envtemplate", environment).should == "/my/modules/mymod/templates/envtemplate" + it "returns nil if the module is not found" do + expect(Puppet::Parser::Files.find_template("module_does_not_exist/mytemplate", environment)).to be_nil end - it "should return nil if no template can be found" do - Puppet::Parser::Files.find_template("foomod/envtemplate", environment).should be_nil + it "returns nil if the module is found, but the template is not " do + expect(Puppet::Parser::Files.find_template("mymod/template_does_not_exist", environment)).to be_nil end end describe "when searching for manifests in a module" do - def a_module_in_environment(env, name) - mod = Puppet::Module.new(name, "/one/#{name}", env) - env.stubs(:module).with(name).returns mod - mod.stubs(:match_manifests).with("init.pp").returns(["/one/#{name}/manifests/init.pp"]) + let(:no_manifests_found) { [nil, []] } + + it "ignores invalid module names" do + expect(Puppet::Parser::Files.find_manifests_in_modules("mod.has.invalid.name/init.pp", environment)).to eq(no_manifests_found) end it "returns no files when no module is found" do - module_name, files = Puppet::Parser::Files.find_manifests_in_modules("not_here_module/foo", environment) - expect(files).to be_empty - expect(module_name).to be_nil + expect(Puppet::Parser::Files.find_manifests_in_modules("not_here_module/init.pp", environment)).to eq(no_manifests_found) end - it "should return the name of the module and the manifests from the first found module" do - a_module_in_environment(environment, "mymod") + it "returns the name of the module and the manifests from the first found module" do + expect(Puppet::Parser::Files.find_manifests_in_modules("mymod/init.pp", environment) + ).to eq(["mymod", [mymod_init_manifest]]) + end - Puppet::Parser::Files.find_manifests_in_modules("mymod/init.pp", environment).should == - ["mymod", ["/one/mymod/manifests/init.pp"]] + it "always includes init.pp if present" do + expect(Puppet::Parser::Files.find_manifests_in_modules("mymod/another.pp", environment) + ).to eq(["mymod", [mymod_init_manifest, mymod_another_manifest]]) end it "does not find the module when it is a different environment" do different_env = Puppet::Node::Environment.create(:different, []) - a_module_in_environment(environment, "mymod") - Puppet::Parser::Files.find_manifests_in_modules("mymod/init.pp", different_env).should_not include("mymod") + expect(Puppet::Parser::Files.find_manifests_in_modules("mymod/init.pp", different_env)).to eq(no_manifests_found) end end end