From b37891edd74115caf860037e88255e7bc0482b0f Mon Sep 17 00:00:00 2001 From: Tomo Suzuki Date: Tue, 1 Sep 2026 20:19:23 +0000 Subject: [PATCH] fix(generator): rejoin split doc URLs (b/153077040) and strip non-existent message links (b/158466893) --- gapic-generator/lib/gapic/formatting_utils.rb | 33 +++++++++++-- .../test/gapic/formatting_utils_test.rb | 46 +++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/gapic-generator/lib/gapic/formatting_utils.rb b/gapic-generator/lib/gapic/formatting_utils.rb index 3925843ae..722027f18 100644 --- a/gapic-generator/lib/gapic/formatting_utils.rb +++ b/gapic-generator/lib/gapic/formatting_utils.rb @@ -32,6 +32,13 @@ module FormattingUtils "version", "yield", "yieldparam", "yieldreturn" ].freeze + # Non-existent messages referenced in proto documentation comments (b/158466893). + # Cross-references to these messages (or their fields) cannot be resolved, so the links + # are stripped to avoid broken documentation references. + @non_existent_messages = [ + "google.cloud.automl.v1.ColumnSpec" + ].freeze + class << self ## # Given an enumerable of lines, performs yardoc formatting, including: @@ -52,9 +59,8 @@ class << self # def format_doc_lines api, lines, disable_xrefs: false, transport: nil transport ||= api&.default_transport || :grpc - # Tracks fenced blocks, multiline inline code spans, and indented code blocks. - in_fence = false - in_code_span = false + lines = rejoin_split_urls lines + in_fence = in_code_span = false in_block = nil base_indent = 0 (lines - @omit_lines).map do |line| @@ -99,6 +105,21 @@ def format_number value private + def rejoin_split_urls lines + return lines if lines.empty? + + # Fix for misformatted markdown links across line breaks (b/153077040). + # Callers may pass lines with trailing newlines (e.g., from String#each_line in schema wrappers) + # or without trailing newlines (e.g., from String#split("\n") in GemPresenter#readme_description). + # We must preserve the presence or absence of trailing newlines on each element. + has_newlines = lines.any? { |l| l.end_with? "\n" } + if has_newlines + lines.join.gsub(%r{https:\n\s*//}, "https://").each_line.to_a + else + lines.join("\n").gsub(%r{https:\n\s*//}, "https://").split("\n", -1) + end + end + def update_indent_state in_block, base_indent, line, indent if in_block != true && @list_element_detector =~ line in_block = false @@ -155,6 +176,12 @@ def sanitize_prose_tags text def format_line_xrefs api, line, disable_xrefs, transport while (m = @xref_detector.match line) + # Remove links to known non-existent messages (b/158466893) + if @non_existent_messages.any? { |msg| m[:addr] == msg || m[:addr].start_with?("#{msg}.") } + line = "#{m[:pre]}#{m[:text]}#{m[:post]}" + next + end + entity = api.lookup m[:addr] is_mixin_field_addr = Gapic::Model::Mixins.mixin_message_field_address?( m[:addr], diff --git a/gapic-generator/test/gapic/formatting_utils_test.rb b/gapic-generator/test/gapic/formatting_utils_test.rb index 5051eb4f1..85a96baba 100644 --- a/gapic-generator/test/gapic/formatting_utils_test.rb +++ b/gapic-generator/test/gapic/formatting_utils_test.rb @@ -723,4 +723,50 @@ def test_multiline_code_span_resets_on_blank_line "New paragraph with \\\\{100, 200}\n" ], result end + + def test_format_doc_lines_rejoin_split_urls + result = Gapic::FormattingUtils.format_doc_lines nil, [ + "[`google.rpc.Status`](https:\n", + "//github.com/googleapis/googleapis/blob/master/google/rpc/status.proto)\n" + ] + assert_equal [ + "[`google.rpc.Status`](https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto)\n" + ], result + end + + def test_format_doc_lines_rejoin_split_urls_without_trailing_newlines + result = Gapic::FormattingUtils.format_doc_lines nil, [ + "[`google.rpc.Status`](https:", + "//github.com/googleapis/googleapis/blob/master/google/rpc/status.proto)" + ] + assert_equal [ + "[`google.rpc.Status`](https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto)" + ], result + end + + def test_format_doc_lines_without_trailing_newlines_preserves_lines + result = Gapic::FormattingUtils.format_doc_lines nil, [ + "## Overview", + "", + "Typical Garbage Service overview.", + "", + "## Resources" + ] + assert_equal [ + "## Overview", + "", + "Typical Garbage Service overview.", + "", + "## Resources" + ], result + end + + def test_format_doc_lines_non_existent_messages + result = Gapic::FormattingUtils.format_doc_lines nil, [ + "The column names must contain [display_name-s][google.cloud.automl.v1.ColumnSpec.display_name]!\n" + ] + assert_equal [ + "The column names must contain display_name-s!\n" + ], result + end end