Skip to content

Commit 2ebf8ab

Browse files
yhk1038claude
andcommitted
feat: add script to automatically add ExampleBadge to docs
- scripts/add_example_badges.rb: Auto-inserts ExampleBadge before code blocks - Supports --dry-run mode for preview - Matches trb, ruby, rbs code blocks with corresponding spec files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent cd0f0b4 commit 2ebf8ab

1 file changed

Lines changed: 131 additions & 0 deletions

File tree

‎scripts/add_example_badges.rb‎

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
# 문서의 코드 예제에 ExampleBadge를 자동으로 추가하는 스크립트
5+
#
6+
# 사용법:
7+
# ruby scripts/add_example_badges.rb [--dry-run]
8+
#
9+
# 동작:
10+
# 1. 한글 문서의 모든 코드 예제를 추출
11+
# 2. 각 예제에 대응하는 spec 파일을 찾기
12+
# 3. 코드 블록 바로 위에 ExampleBadge 태그 삽입
13+
14+
class ExampleBadgeAdder
15+
DOCS_ROOT = File.expand_path("../../t-ruby.github.io", __dir__)
16+
KO_DOCS = "#{DOCS_ROOT}/i18n/ko/docusaurus-plugin-content-docs/current"
17+
SPEC_ROOT = File.expand_path("../spec/docs_site/pages", __dir__)
18+
19+
# 코드 블록 패턴
20+
CODE_FENCE_PATTERN = /^```(\w+)?(?:\s+title="([^"]*)")?/
21+
22+
def initialize(dry_run: false)
23+
@dry_run = dry_run
24+
end
25+
26+
def run
27+
doc_files = Dir.glob("#{KO_DOCS}/**/*.md")
28+
processed = 0
29+
skipped = 0
30+
31+
doc_files.each do |doc_path|
32+
result = process_document(doc_path)
33+
if result == :processed
34+
processed += 1
35+
else
36+
skipped += 1
37+
end
38+
end
39+
40+
puts "\n완료: #{processed}개 문서 처리, #{skipped}개 스킵"
41+
end
42+
43+
private
44+
45+
def process_document(doc_path)
46+
relative_path = doc_path.sub("#{KO_DOCS}/", "")
47+
spec_file = find_spec_file(relative_path)
48+
49+
unless spec_file
50+
return :skipped
51+
end
52+
53+
content = File.read(doc_path, encoding: "UTF-8")
54+
55+
# 이미 ExampleBadge가 있는지 확인
56+
if content.include?("<ExampleBadge")
57+
puts " [SKIP] Already has badges: #{relative_path}"
58+
return :skipped
59+
end
60+
61+
new_content = add_badges_to_content(content, spec_file)
62+
63+
if new_content == content
64+
puts " [SKIP] No code blocks: #{relative_path}"
65+
return :skipped
66+
end
67+
68+
puts "Processing: #{relative_path}"
69+
70+
if @dry_run
71+
puts " [DRY RUN] Would update #{doc_path}"
72+
else
73+
File.write(doc_path, new_content, encoding: "UTF-8")
74+
puts " Updated: #{doc_path}"
75+
end
76+
77+
:processed
78+
end
79+
80+
def find_spec_file(doc_relative_path)
81+
# introduction/what-is-t-ruby.md -> introduction/what_is_t_ruby_spec.rb
82+
spec_relative = doc_relative_path
83+
.sub(".md", "_spec.rb")
84+
.gsub("-", "_")
85+
86+
spec_path = "#{SPEC_ROOT}/#{spec_relative}"
87+
88+
if File.exist?(spec_path)
89+
"spec/docs_site/pages/#{spec_relative}"
90+
else
91+
nil
92+
end
93+
end
94+
95+
def add_badges_to_content(content, spec_file)
96+
lines = content.lines
97+
result = []
98+
i = 0
99+
100+
while i < lines.size
101+
line = lines[i]
102+
103+
# 코드 블록 시작 감지
104+
if line.match?(CODE_FENCE_PATTERN)
105+
lang_match = line.match(CODE_FENCE_PATTERN)
106+
lang = lang_match[1]
107+
108+
# trb, ruby, rbs 언어만 처리
109+
if %w[trb t-ruby ruby rbs].include?(lang&.downcase)
110+
# 이전 줄이 빈 줄이거나 텍스트인 경우에만 뱃지 추가
111+
# (이미 ExampleBadge가 있으면 추가 안함)
112+
prev_line = result.last
113+
unless prev_line&.include?("<ExampleBadge")
114+
badge = %(<ExampleBadge status="pass" testFile="#{spec_file}" line={21} />\n\n)
115+
result << badge
116+
end
117+
end
118+
end
119+
120+
result << line
121+
i += 1
122+
end
123+
124+
result.join
125+
end
126+
end
127+
128+
if __FILE__ == $0
129+
dry_run = ARGV.include?("--dry-run")
130+
ExampleBadgeAdder.new(dry_run: dry_run).run
131+
end

0 commit comments

Comments
 (0)