diff --git a/lib/yard/cli/yardoc.rb b/lib/yard/cli/yardoc.rb index f40e4dd15..18a955086 100644 --- a/lib/yard/cli/yardoc.rb +++ b/lib/yard/cli/yardoc.rb @@ -411,14 +411,27 @@ def print_list def add_extra_files(*files) files.map! {|f| f.include?("*") ? Dir.glob(f) : f }.flatten! files.each do |file| - if File.file?(file) + if extra_file_valid?(file) options.files << CodeObjects::ExtraFileObject.new(file) - else - log.warn "Could not find extra file: #{file}" end end end + # @param file [String] the filename to validate + # @param check_exists [Boolean] whether the file should exist on disk + # @return [Boolean] whether the file is allowed to be used + def extra_file_valid?(file, check_exists = true) + if file =~ %r{^(?:\.\./|/)} + log.warn "Invalid file: #{file}" + false + elsif check_exists && !File.file?(file) + log.warn "Could not find file: #{file}" + false + else + true + end + end + # Parses the file arguments into Ruby files and extra files, which are # separated by a '-' element. # @@ -644,10 +657,8 @@ def output_options(opts) opts.on('-r', '--readme FILE', '--main FILE', 'The readme file used as the title page', ' of documentation.') do |readme| - if File.file?(readme) + if extra_file_valid?(readme) options.readme = CodeObjects::ExtraFileObject.new(readme) - else - log.warn "Could not find readme file: #{readme}" end end @@ -658,12 +669,9 @@ def output_options(opts) opts.on('--asset FROM[:TO]', 'A file or directory to copy over to output ', ' directory after generating') do |asset| - re = %r{^(?:\.\./|/)} from, to = *asset.split(':').map {|f| File.cleanpath(f, true) } to ||= from - if from =~ re || to =~ re - log.warn "Invalid file '#{asset}'" - else + if extra_file_valid?(from, false) && extra_file_valid?(to, false) assets[from] = to end end diff --git a/spec/cli/yardoc_spec.rb b/spec/cli/yardoc_spec.rb index 2525ec52c..5b39bd263 100644 --- a/spec/cli/yardoc_spec.rb +++ b/spec/cli/yardoc_spec.rb @@ -205,10 +205,10 @@ def self.should_accept(*args, &block) end it "aliases --main to the --readme flag" do - readme = File.join(File.dirname(__FILE__), '..', '..', 'README.md') - - @yardoc.parse_arguments('--main', readme) - expect(@yardoc.options.readme).to eq CodeObjects::ExtraFileObject.new(readme, '') + Dir.chdir(File.join(File.dirname(__FILE__), '..', '..')) do + @yardoc.parse_arguments('--main', 'README.md') + expect(@yardoc.options.readme).to eq CodeObjects::ExtraFileObject.new('README.md', '') + end end it "selects a markup provider when --markup-provider or -mp is set" do @@ -607,15 +607,25 @@ def foo; end end it "warns if extra file is not found" do - expect(log).to receive(:warn).with(/Could not find extra file: UNKNOWN/) + expect(log).to receive(:warn).with(/Could not find file: UNKNOWN/) @yardoc.parse_arguments(*%w(- UNKNOWN)) end it "warns if readme file is not found" do - expect(log).to receive(:warn).with(/Could not find readme file: UNKNOWN/) + expect(log).to receive(:warn).with(/Could not find file: UNKNOWN/) @yardoc.parse_arguments(*%w(-r UNKNOWN)) end + it "warns on absolute paths in extra files" do + expect(log).to receive(:warn).with(%r{Invalid file: /path/to/file}) + @yardoc.parse_arguments(*%w(- /path/to/file)) + end + + it "warns on absolute paths in readme" do + expect(log).to receive(:warn).with(%r{Invalid file: /path/to/file}) + @yardoc.parse_arguments(*%w(-r /path/to/file)) + end + it "uses first file as readme if no readme is specified when using --one-file" do expect(Dir).to receive(:glob).with('README{,*[^~]}').and_return [] expect(Dir).to receive(:glob).with('lib/*.rb').and_return(['lib/foo.rb'])