From 83b528abc3d0bf927cfa1041839f04cfe334d099 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@ruby-lang.org> Date: Sat, 16 Apr 2022 21:16:51 +0900 Subject: [PATCH] New line-oriented `.document` file format Introduce the new format similar to the `.gitignore` file by starting with the comment `rdoc.document: 1`. - one pattern per line - negative pattern starting with `!` - escaping space and `#` by a backslash --- lib/rdoc/rdoc.rb | 62 ++++++++++++++++++++++++++++++++++--- test/rdoc/test_rdoc_rdoc.rb | 43 +++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 5 deletions(-) diff --git a/lib/rdoc/rdoc.rb b/lib/rdoc/rdoc.rb index a7f9239b62..04a00cd347 100644 --- a/lib/rdoc/rdoc.rb +++ b/lib/rdoc/rdoc.rb @@ -245,15 +245,67 @@ def output_flag_file(op_dir) # The .document file contains a list of file and directory name patterns, # representing candidates for documentation. It may also contain comments # (starting with '#') + # + # If the first line is the comment starts with +rdoc.document:+ + # (case-insensitive) followed by a version string, the file is + # parsed as per the version. If a version is not written, it is + # defaulted to 0. + # + # version 0:: + # + # The file will be parsed as white-space separated glob patterns. + # + # - A <tt>#</tt> in middle starts a comment. + # + # - Multiple patterns can be in a single line. + # + # - That means patterns cannot contain white-spaces and <tt>#</tt> + # marks. + # + # version 1:: + # + # The file will be parsed as single glob pattern per each line. + # + # - Only lines starting with <tt>#</tt> at the first colmun are + # comments. A <tt>#</tt> in middle is a part of the pattern. + # + # - Patterns starting with <tt>#</tt> need to be prefixed with a + # backslash (<tt>\\</tt>). + # + # - Leading spaces are not stripped while trailing spaces which + # are not escaped with a backslash are stripped. + # + # - The pattern starting with <tt>!</tt> is a negative pattern, + # which rejects matching files. def parse_dot_doc_file in_dir, filename - # read and strip comments - patterns = File.read(filename).gsub(/#.*/, '') - result = {} + patterns = rejects = nil + + content = File.read(filename) + version = content[/\A#+\s*rdoc\.document:\s*\K\S+/i]&.to_i || 0 + if version >= 1 + content.each_line(chomp: true) do |line| + next if line.start_with?("#") # skip comments + line.sub!(/(?<!\\)\s*$/, "") # rstrip unescaped trailing spaces + (line.sub!(/\A!/, "") ? (rejects ||= []) : (patterns ||= [])) << line + end + else + # read and strip comments + patterns = content.gsub(/#.*/, '').split(' ') + end - patterns.split(' ').each do |patt| - candidates = Dir.glob(File.join(in_dir, patt)) + if patterns + patterns.each {|patt| patt.sub!(/\A\/+/, "")} + candidates = Dir.glob(patterns, base: in_dir) + if rejects + rejects.each {|patt| patt.sub!(/\A\/+/, "")} + flag = File::FNM_PATHNAME + candidates.delete_if do |name| + rejects.any? {|patt| File.fnmatch?(patt, name, flag)} + end + end + candidates.map! {|name| File.join(in_dir, name)} result.update normalized_file_list(candidates, false, @options.exclude) end diff --git a/test/rdoc/test_rdoc_rdoc.rb b/test/rdoc/test_rdoc_rdoc.rb index 9c94988ffd..ae7925a6ec 100644 --- a/test/rdoc/test_rdoc_rdoc.rb +++ b/test/rdoc/test_rdoc_rdoc.rb @@ -177,6 +177,49 @@ def test_normalized_file_list_with_dot_doc assert_equal expected_files, files end + def test_normalized_file_list_with_dot_doc_version_1 + expected_files = [] + files = temp_dir do |dir| + a = 'a.rb' + b = 'b.rb' + a_b = 'a.rb b.rb' + FileUtils.touch a + FileUtils.touch b + FileUtils.touch a_b + + File.open('.document', 'w') do |f| + f.puts '# rdoc.document: 1' + f.puts a_b + end + expected_files << File.expand_path(a_b, dir) + + @rdoc.normalized_file_list [dir] + end + + assert_equal expected_files, files.keys + end + + def test_normalized_file_list_with_dot_doc_negative_pattern + expected_files = [] + files = temp_dir do |dir| + a = 'a.rb' + b = 'b.rb' + FileUtils.touch a + FileUtils.touch b + + File.open('.document', 'w') do |f| + f.puts '# rdoc.document: 1' + f.puts '*.rb' + f.puts '!b.rb' + end + expected_files << File.expand_path(a, dir) + + @rdoc.normalized_file_list [dir] + end + + assert_equal expected_files, files.keys + end + def test_normalized_file_list_with_dot_doc_overridden_by_exclude_option expected_files = [] files = temp_dir do |dir|