Bookworm: Rubocop 기반의 대규모 Ruby 코드 크롤러

[EN] A side gig for RuboCop, the Bookworm code crawler / David T. Crosby @dafyddcrosby

3줄 요약

  • Meta는 대규모 Chef 코드베이스 관리를 위해 Rubocop 기반의 코드 크롤러 'Bookworm'을 개발했습니다.
  • Bookworm은 기존 린터의 단일 파일 분석 한계를 넘어, 코드 패턴 매칭을 통해 전체 코드베이스의 심층적인 분석과 대규모 리팩토링을 가능하게 합니다.
  • 이 도구는 코드베이스의 '낡은 코드(croft)'를 안전하게 식별하고 제거하는 데 기여하며, 대규모 Ruby 환경에서의 코드 품질 관리 및 효율성을 극대화합니다.

본 강연은 Meta의 프로덕션 엔지니어인 David Crosby가 Rubocop 기반으로 구축된 코드 크롤러인 'Bookworm'에 대해 소개합니다. Meta는 10년 이상 Chef(Ruby DSL 기반의 구성 관리 도구)를 광범위하게 사용하여 수백만 대의 서버를 관리하고 있으며, 이러한 거대한 Ruby 코드베이스의 효율적인 관리와 품질 유지를 위해 Bookworm을 개발했습니다. 기존의 코드 분석 도구들이 가진 한계를 극복하고 대규모 환경에서 코드의 안전성과 관리 용이성을 확보하는 것이 Bookworm 개발의 핵심 동기입니다.

기존에 Meta는 Chef 코드 관리를 위해 Food Critic이라는 린터를 사용했으나, 이는 Rubocop보다 먼저 개발되었고 2016년 이후에는 지원이 중단되었습니다. Rubocop은 스타일 가이드 준수에 강점이 있었으나, Food Critic이 제공하지 못했던 중요한 기능인 ‘자동 수정(autocorrection)’을 제공합니다. 강연자는 산업 현장의 ‘위험 통제 계층(Hierarchy of Hazard Controls)’에 비유하여, 단순히 문제를 지적하는 린터(행정적 통제)보다 코드를 자동으로 안전하게 수정하는 기능(공학적 통제)이 훨씬 효과적이라고 강조합니다. Rubocop의 자동 수정 기능은 개발자들이 광범위한 전문성 수준을 가질 때, 단순히 문제를 지적하는 것을 넘어 실제 코드 베이스를 개선하는 데 필수적입니다.

그러나 Rubocop 역시 단일 파일 단위로 작동한다는 한계가 있습니다. 이는 여러 파일에 걸쳐 있는 코드 패턴을 분석하거나, Chef의 ‘쿡북(cookbooks)’ 간의 복잡한 의존성 문제를 해결하는 데는 부적합합니다. 특히 Chef 코드베이스에서는 쿡북 간의 알림(notifications), 전이적 의존성(transitive dependencies), 그리고 시간이 지남에 따라 쌓이는 ‘낡은 코드(croft)’를 식별하고 안전하게 제거하는 것이 큰 도전 과제였습니다. 이러한 문제들은 런타임에 예상치 못한 오류를 유발하거나 코드베이스의 복잡성을 가중시킵니다.

Bookworm은 이러한 대규모 코드베이스의 문제를 해결하기 위해 설계되었습니다. 그 작동 방식은 크게 세 단계로 나뉩니다. 첫째, 파일 크롤링을 통해 metadata.rb, 레시피 코드, 속성(attributes) 등 Chef 쿡북의 다양한 정보를 수집합니다. 둘째, 수집된 정보는 ‘지식 베이스(knowledge base)’라는 해시 구조에 저장되며, Rubocop의 강력한 ‘노드 패턴 API(Node Pattern API)’를 사용하여 이 지식 베이스에 대해 반복적으로 패턴 매칭을 수행합니다. 이를 통해 코드에서 추출된 AST(Abstract Syntax Tree) 정보를 기반으로 복잡한 코드 패턴을 식별합니다. 셋째, 이 지식 베이스를 활용하여 보고서를 생성합니다. 이 보고서는 단순한 쿡북 목록부터 특정 패턴을 가진 코드의 트랜스파일러(transpiler)까지 다양한 형태로 제공될 수 있습니다. 예를 들어, 어떤 쿡북이 다른 쿡북에 의해 전혀 참조되지 않는 ‘리프 쿡북(leaf cookbooks)’인지를 식별하여 안전하게 삭제할 수 있도록 돕습니다.

Bookworm의 설계 철학은 ‘사용 용이성’과 ‘효율성’에 있습니다. grep이나 쉘 스크립트보다 더 나은 경험을 제공하며, 각 처리 단계에 전략적인 브레이크포인트를 제공하여 디버깅 및 프로파일링을 용이하게 합니다. 또한, Rubocop의 노드 패턴 API에 익숙한 사용자라면 Bookworm을 쉽게 사용할 수 있도록 학습 곡선을 최소화했습니다. 대규모 환경의 특성을 고려하여, 각 규칙이 전체 성능에 영향을 주지 않도록 관련 파일에만 규칙을 적용하는 최적화도 이루어졌습니다. 이는 수십만 라인의 코드베이스에서 매우 중요한 요소입니다.

결론적으로 Bookworm은 Meta와 같은 대규모 Ruby 및 Chef 환경에서 코드 품질을 관리하고 대규모 리팩토링을 수행하는 데 필수적인 도구입니다. Rubocop의 강력한 AST 분석 및 노드 패턴 매칭 기능을 활용하여 단일 파일 린터의 한계를 극복하고, 코드베이스 전반에 걸친 복잡한 관계를 파악하고 자동 수정하는 능력을 제공합니다. 1,000줄 미만의 간결한 코드로 이루어진 이 프레임워크는 오픈 소스로 공개되어 있으며, Chef 외에도 Rails 애플리케이션 등 다른 Ruby 프로젝트나 심지어 다른 언어의 코드 분석에도 확장될 잠재력을 가지고 있습니다. Bookworm은 개발자들이 코드베이스를 '머릿속에 담고' 더 안전하고 효율적으로 관리할 수 있도록 돕는 혁신적인 솔루션입니다.