Module: Vivlio::Starter::CLI::PreProcessCommands::LinkImageValidator
- Defined in:
- lib/vivlio/starter/cli/pre_process/link_image_validator.rb
Defined Under Namespace
Classes: ImageIssue, LinkIssue, ValidationReport
Class Method Summary collapse
-
.any_issues? ⇒ Boolean
蓄積されたレポートにエラー(issue)が1件以上あるか判定する.
-
.any_verification_enabled?(config: resolve_config) ⇒ Boolean
検証が有効か判定する.
-
.check_external_urls! ⇒ Object
蓄積された外部 URL に対して HTTP 到達性チェックを実行する.
-
.print_summary ⇒ Object
検証結果のサマリーを表示する.
-
.record_code_include_error(filename, line_number, code_name) ⇒ Object
コードインクルードエラーをレポートに記録する MarkdownTransformer から呼ばれ、preflight の終了コード判定に反映させる.
-
.reset! ⇒ Object
レポート蓄積をリセットする(ビルド開始時に呼ぶ).
-
.validate(content, filename, source_path: nil, config: resolve_config) ⇒ Object
ファイル単位の検証を実行し、レポートを蓄積する.
Class Method Details
.any_issues? ⇒ Boolean
蓄積されたレポートにエラー(issue)が1件以上あるか判定する
192 193 194 195 196 |
# File 'lib/vivlio/starter/cli/pre_process/link_image_validator.rb', line 192 def any_issues? @monitor.synchronize do @reports.any? { |r| r.image_issues.any? || r.link_issues.any? } end end |
.any_verification_enabled?(config: resolve_config) ⇒ Boolean
検証が有効か判定する
187 188 189 |
# File 'lib/vivlio/starter/cli/pre_process/link_image_validator.rb', line 187 def any_verification_enabled?(config: resolve_config) config[:verify_images] || config[:verify_bare_urls] || config[:verify_external_links] end |
.check_external_urls! ⇒ Object
蓄積された外部 URL に対して HTTP 到達性チェックを実行する
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/vivlio/starter/cli/pre_process/link_image_validator.rb', line 101 def check_external_urls! config = resolve_config return unless config[:verify_external_links] urls = @monitor.synchronize { @external_urls.dup } return if urls.empty? # URL を重複排除(同じ URL は 1 回だけチェック) unique_urls = urls.uniq { it[:url] } Common.log_action("[検証] 外部 URL の到達性を確認しています(#{unique_urls.size} 件)…") results = check_urls_batch(unique_urls, config) # 結果をレポートに反映 results.each do |result| next if result[:ok] issue = LinkIssue.new( filename: result[:filename], line_number: result[:line_number], url: result[:url], issue_type: :unreachable, status_code: result[:status_code], message: result[:message] ) add_link_issue_to_report(result[:filename], issue) end end |
.print_summary ⇒ Object
検証結果のサマリーを表示する
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/vivlio/starter/cli/pre_process/link_image_validator.rb', line 131 def print_summary reports = @monitor.synchronize { @reports.dup } return if reports.empty? total_missing_image = reports.sum { it.image_issues.count { |i| i.issue_type == :missing } } total_missing_code = reports.sum { it.image_issues.count { |i| i.issue_type == :missing_code } } total_link = reports.sum { it.link_issues.size } if total_missing_image.zero? && total_missing_code.zero? && total_link.zero? Common.log_info('リンク・画像の検証が完了しました(良好な状態です)') return end # --- サマリー集計 --- detail_lines = [] detail_lines << "画像: #{total_missing_image} 件の課題(存在しない画像: #{total_missing_image})" if total_missing_image.positive? detail_lines << "ソースコード: #{total_missing_code} 件の課題(存在しないファイル: #{total_missing_code})" if total_missing_code.positive? if total_link.positive? = reports.sum { it.link_issues.count { |i| i.issue_type == :bare_url } } unreachable = reports.sum { it.link_issues.count { |i| i.issue_type == :unreachable } } dangerous = reports.sum { it.link_issues.count { |i| i.issue_type == :dangerous_scheme } } parts = [] parts << "危険スキーム: #{dangerous}" if dangerous.positive? parts << "リンク切れ: #{unreachable}" if unreachable.positive? parts << "裸 URL: #{}" if .positive? detail_lines << "リンク: #{total_link} 件の問題(#{parts.join(', ')})" end config = resolve_config detail_lines << '外部URL到達性チェック: スキップ(--verify-links で有効化)' unless config[:verify_external_links] Common.log_summary('リンク・画像検証の結果:', detail: detail_lines.join("\n")) # --- 危険スキームの詳細(セキュリティ上の重要度が高いため先頭)--- reports.each do |report| report.link_issues.select { it.issue_type == :dangerous_scheme }.each do |issue| Common.log_warn( "#{issue.filename}:#{issue.line_number} - 危険なスキームを検出しました", detail: "URL: #{issue.url}\n#{issue.}" ) end end # --- リンク切れの詳細 --- reports.each do |report| report.link_issues.select { it.issue_type == :unreachable }.each do |issue| Common.log_error( "#{issue.filename}:#{issue.line_number} - リンク切れを検出しました", detail: "URL: #{issue.url} → #{issue.}" ) end end end |
.record_code_include_error(filename, line_number, code_name) ⇒ Object
コードインクルードエラーをレポートに記録するMarkdownTransformer から呼ばれ、preflight の終了コード判定に反映させる
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/vivlio/starter/cli/pre_process/link_image_validator.rb', line 203 def record_code_include_error(filename, line_number, code_name) issue = ImageIssue.new( filename:, line_number:, image_path: code_name, issue_type: :missing_code ) @monitor.synchronize do report = @reports.find { it.filename == filename } if report idx = @reports.index(report) @reports[idx] = ValidationReport.new( filename: report.filename, image_issues: report.image_issues + [issue], link_issues: report.link_issues ) else # process_code_includes! は validate の後に実行されるため、 # レポートが存在しない場合は新規作成する @reports << ValidationReport.new(filename:, image_issues: [issue], link_issues: []) end end end |
.reset! ⇒ Object
レポート蓄積をリセットする(ビルド開始時に呼ぶ)
53 54 55 56 57 58 |
# File 'lib/vivlio/starter/cli/pre_process/link_image_validator.rb', line 53 def reset! @monitor.synchronize do @reports = [] @external_urls = [] end end |
.validate(content, filename, source_path: nil, config: resolve_config) ⇒ Object
ファイル単位の検証を実行し、レポートを蓄積する
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/vivlio/starter/cli/pre_process/link_image_validator.rb', line 65 def validate(content, filename, source_path: nil, config: resolve_config) source_content = source_path && File.exist?(source_path) ? File.read(source_path, encoding: 'utf-8') : nil image_issues = config[:verify_images] ? scan_missing_images(content, filename) : [] link_issues = config[:verify_bare_urls] ? (content, filename) : [] # 行番号を元ファイルの行番号に補正する if source_content image_issues = image_issues.map { correct_line_number(it, source_content) } link_issues = link_issues.map { correct_link_line_number(it, source_content) } end # 補正後の行番号でログを出力 link_issues.select { it.issue_type == :bare_url }.each do |issue| Common.log_warn( "#{issue.filename}:#{issue.line_number} - 裸 URL を検出しました", detail: "URL: #{issue.url}" ) end # セキュリティ検証(11-1): 危険スキームの検出は常時有効 # file:// / javascript: 等は --no-verify でも無効化しない link_issues += scan_dangerous_schemes(content, filename) # 外部 URL チェック用に URL を蓄積(後でバッチ実行) if config[:verify_external_links] urls = extract_external_urls(content, filename) @monitor.synchronize { @external_urls.concat(urls) } end report = ValidationReport.new(filename:, image_issues:, link_issues:) @monitor.synchronize { @reports << report } report end |