Module: VivlioStarter::CLI::BuildCommands::OutputHelpers

Included in:
SamovarCommands::BuildCommand
Defined in:
lib/vivlio_starter/cli/build/output_helpers.rb

Overview

ビルド結果出力ヘルパーモジュール

Constant Summary collapse

STEP5_LABEL =
'Step  5 (convert sections html)'
STEP5B_LABEL =
'Step 5b (generate part title pages)'
STEP5_AGG_LABEL =
'Step  5 (generate sections / part pages)'
SUM_LABEL =

集計行の見出し。数値列の桁を揃えるため ASCII のみで書く (日本語は 1 文字が 2 桁ぶんの幅を取り、%-Ns の桁揃えが崩れる)。

'TOTAL (sum of steps)'
WALL_LABEL =
'WALL (elapsed)'
PARALLEL_MARK =

子枝で並行に走ったステップの印。数値列より右なので桁揃えには影響しない

'   [epub 枝・PDF 枝と並行]'

Instance Method Summary collapse

Instance Method Details

#aggregate_step_timings(build_timings) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/vivlio_starter/cli/build/output_helpers.rb', line 133

def aggregate_step_timings(build_timings)
  label_groups = {}
  aggregated = []
  needs_merge = build_timings.any? { |label, _| label == STEP5_LABEL } &&
                build_timings.any? { |label, _| label == STEP5B_LABEL }

  build_timings.each do |label, duration|
    if needs_merge && [STEP5_LABEL, STEP5B_LABEL].include?(label)
      entry = aggregated.find { |(lbl, _)| lbl == STEP5_AGG_LABEL }
      if entry
        entry[1] += duration
      else
        aggregated << [STEP5_AGG_LABEL, duration]
      end
      label_groups[STEP5_AGG_LABEL] ||= []
      label_groups[STEP5_AGG_LABEL] << label
    else
      aggregated << [label, duration]
      label_groups[label] = [label]
    end
  end

  [aggregated, label_groups]
end

#calculate_extra_spaces(duration) ⇒ Object

余白計算ヘルパー



126
127
128
129
130
131
# File 'lib/vivlio_starter/cli/build/output_helpers.rb', line 126

def calculate_extra_spaces(duration)
  return 0 if duration >= 100
  return 1 if duration >= 10

  2
end

ビルドタイミングをコンソールに出力する

  • 通常時: print_created_files_message に合計時間を渡す形で表示するため何もしない
  • debugモード時: ステップ別の詳細テーブルを表示

Parameters:

  • wall_time (Float, nil) (defaults to: nil)

    実測の経過秒。枝を並列に走らせるとステップ計時の 合計より短くなるため、逐次合計と並べて出す(隠れた枝の劣化に気付けるように・§3.5)

  • parallel_labels (Array<String>) (defaults to: [])

    子枝で並行に走ったステップのラベル。 壁時計には現れないぶんなので、その旨を行末へ添える



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
# File 'lib/vivlio_starter/cli/build/output_helpers.rb', line 42

def print_build_timings(build_timings, wall_time: nil, parallel_labels: [])
  aggregated, label_groups = aggregate_step_timings(build_timings)
  return if aggregated.empty?

  # 通常時は print_created_files_message(files, build_timings:) で表示済みのため何もしない
  return unless Common.current_log_level >= 3

  # --- debug モード: ステップ別詳細テーブル ---
  total = aggregated.map { |(_, dt)| dt }.inject(0.0, :+)
  label_width = aggregated.map { |(label, _)| label.to_s.length }.max || 0
  label_width = [label_width, SUM_LABEL.length, 34].max
  value_width = 7

  Common.log_always "\n== Build Step Timings =="
  vs_timings = Common.consume_vivliostyle_build_timings
  vs_map = vs_timings.group_by { |entry| entry[:label].to_s }
  sub_label = '(vivliostyle build)'

  aggregated.each do |label, dt|
    raw_label = label.to_s
    value_text = format("%#{value_width}.2fs", dt)
    label_text = format("%-#{label_width}s", raw_label)
    line = "  - #{label_text} #{value_text}"
    line += PARALLEL_MARK if parallel_labels.include?(raw_label)
    Common.log_always line

    original_labels = label_groups[raw_label] || [raw_label]
    entries = original_labels.flat_map { |original| vs_map[original] }.compact.flatten
    next unless entries&.any?

    value_start_idx = line.length - value_text.length
    indent = ' ' * 4

    entries.each do |entry|
      entry_value = format('(%.2fs)', entry[:duration])
      extra_spaces = calculate_extra_spaces(entry[:duration])
      target_index = value_start_idx + extra_spaces
      label_segment = format("%-#{label_width}s", sub_label)
      base_prefix = "#{indent}#{label_segment} "
      base_prefix += ' ' * (target_index - base_prefix.length) if base_prefix.length < target_index
      Common.log_always("#{base_prefix}#{entry_value}")
    end
  end
  # 逐次合計を残すのは、並列化後も「どのステップが重いか」を現状と比較できる
  # ようにするため。壁時計だけにすると、隠れた枝の劣化に気付けなくなる(§3.5)。
  Common.log_always format("  = %-#{label_width}s %#{value_width}.2fs", SUM_LABEL, total)
  Common.log_always format("  = %-#{label_width}s %#{value_width}.2fs", WALL_LABEL, wall_time) if wall_time
  Common.log_always "==========================\n"
end

アウトラインデバッグ情報を出力する



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/vivlio_starter/cli/build/output_helpers.rb', line 93

def print_outline_debug_info
  outline_info = Build::OutlineExtractor.last_outline_debug_info
  return unless outline_info && Common.current_log_level >= 3

  Common.log_always '-- Outline Debug Info --'
  outline_info[:items].each do |item|
    next unless item[:chapter] && item[:text]

    level_tag = case item[:level].to_i
                when 1 then 'H1'
                when 2 then 'H2'
                when 3 then 'H3'
                else "H#{item[:level]}"
                end
    Common.log_always format('  %<ch>s / [%<tag>s] %<txt>s -> page %<pg>d',
                              ch: item[:chapter], tag: level_tag, txt: item[:text], pg: item[:page])
  end

  chapter_ranges = outline_info[:chapter_ranges] || {}
  chapter_order  = outline_info[:chapter_order] || []
  return unless chapter_ranges.any?

  Common.log_always '-- Chapter Ranges --'
  order = chapter_order.is_a?(Array) && !chapter_order.empty? ? chapter_order : chapter_ranges.keys.sort
  order.each do |bn|
    rng = chapter_ranges[bn]
    next unless rng

    Common.log_always format('  %<bn>s %<s>s %<e>s', bn: bn, s: rng[0] || '-', e: rng[1] || '-')
  end
end