검색 도구: Glob & Grep

ripgrep 위임, ignore 규칙, glob 파싱, 안전한 인수 전달까지 실제 동작 단위로 정리합니다.

01

개요

Glob과 Grep는 둘 다 ripgrep 기반이지만 하는 일은 다릅니다. Glob은 파일 경로 집합을 찾고, Grep는 파일 내용 안에서 정규식 일치를 찾습니다. 두 도구 모두 속도만이 아니라 안전한 기본값을 중요하게 둡니다.

Glob Grep
검색 대상 파일 경로 파일 내용
입력 패턴 glob 패턴 정규식 + 선택적 include glob
기본 반환 mtime 기준으로 정렬된 경로 files_with_matches
안전 기본값 무한 탐색과 VCS 잡음을 줄임 ignore 규칙, 결과 제한, 긴 줄 제한
다루는 소스 파일: tools/GlobTool/, tools/GrepTool/, utils/ripgrep.ts, utils/glob.ts
02

Glob은 ripgrep 파일 워커를 쓴다

GlobTool은 별도 JavaScript glob 라이브러리보다 ripgrep의 파일 워커를 직접 활용합니다. 그래서 대형 저장소에서도 디렉터리 순회가 빠르고, ignore 규칙과 플랫폼별 경계 사례도 한 경로에서 처리할 수 있습니다.

절대 경로 패턴 분해

절대 경로로 들어온 glob은 먼저 검색 시작 디렉터리와 상대 패턴으로 나뉩니다. 이렇게 해야 ripgrep이 저장소 전체를 걷지 않고 더 좁은 위치에서 출발할 수 있습니다.

// /src/utils/*.ts
searchDir: /src/utils
globPattern: *.ts

// ripgrep은 searchDir 아래에서만 탐색
03

기본 ignore 규칙과 VCS 제외

현재 페이지의 기존 설명은 .gitignore 하나만 언급했지만, 실제 기본 동작은 더 넓습니다. ripgrep은 기본적으로 ignore 파일 계층과 숨김 파일 정책을 반영하며, 도구는 여기에 VCS 디렉터리 제외를 더해 불필요한 탐색을 줄입니다.

기본 ignore 스택

VCS 디렉터리 자체 제외

도구는 검색 대상에서 .git/ 같은 VCS 디렉터리를 실질적으로 배제해 잡음을 줄입니다. 사용자는 보통 버전 관리 메타데이터 안이 아니라 작업 파일 안을 찾고 싶기 때문입니다.

# 개념적 검색 범위
workspace files
  - VCS metadata directories
  - ignored paths from ignore files
  - most hidden paths unless explicitly requested
딥 다이브 - default ignore를 왜 존중하나?

검색 도구는 "가능한 모든 파일"보다 "대부분의 작업에서 바로 쓸 만한 결과"를 더 중요하게 봅니다. 빌드 산출물, 벤더 디렉터리, VCS 메타데이터까지 섞이면 결과 수는 늘어도 유용성은 오히려 떨어집니다.

04

Grep의 3가지 출력 모드

GrepTool은 같은 검색 엔진 위에서 세 가지 응답 형태를 제공합니다. 모델이 파일 목록만 원하는지, 실제 줄 내용을 원하는지, 빈도를 보고 싶은지에 따라 결과를 바꿉니다.

모드 개념 주 용도
files_with_matches 일치한 파일 경로만 반환 후속 Read나 범위 축소
content 일치 줄과 주변 줄 반환 바로 문맥 파악
count 파일별 일치 수 반환 영향 범위 추정

정렬: 경로만 반환하는 모드에서는 수정 시간이 최근인 파일이 앞쪽으로 오도록 정렬되어, 방금 바뀐 코드가 먼저 눈에 띄게 합니다.

05

GrepTool의 include glob 파싱

GrepTool의 include는 단순 문자열 붙이기가 아닙니다. shell에 넘겨 확장시키지 않고, 도구 내부에서 glob 패턴으로 해석한 뒤 ripgrep 인수로 안전하게 전달합니다. 덕분에 brace 패턴이나 확장자 묶음도 일관되게 다룰 수 있습니다.

왜 파싱 단계가 필요한가

# 사용 예
include: "*.{ts,tsx}"

# 개념적 처리
parse include glob
  -> normalize pattern
  -> pass as ripgrep glob argument
06

leading-dash 패턴 안전장치

패턴이 -foo처럼 하이픈으로 시작하면 CLI 도구는 이를 옵션으로 오해할 수 있습니다. 검색 도구는 glob이나 include 패턴을 ripgrep에 넘길 때 이런 입력이 플래그로 해석되지 않도록 안전하게 감쌉니다.

어떤 문제가 생기나

# 안전한 개념
ripgrep args: [ ..., "--glob", pattern ]

# 필요할 때는 옵션 종료 경계도 사용
ripgrep args: [ ..., "--", pattern ]
주의사항

leading dash 문제는 희귀해 보여도 한 번 터지면 "검색 결과가 없다"가 아니라 "도구가 다른 모드로 실행된다"는 식으로 나타날 수 있어 더 헷갈립니다.

07

페이지네이션과 결과 절단

대규모 결과는 그대로 전부 돌려주지 않습니다. GrepTool은 결과를 모은 뒤 offset과 head_limit을 적용해 필요한 창만 잘라 보냅니다.

// 개념적 슬라이싱
results
  .slice(offset)
  .slice(0, effectiveLimit)
08

ripgrep 해석과 vendored 바이너리

ripgrep 해석은 단순히 "시스템에 있으면 쓰고 없으면 끝"이 아닙니다. 도구는 안정적으로 같은 동작을 보장하기 위해 배포물에 포함된 vendored ripgrep를 사용할 수 있고, 그 결과를 캐시해 반복 해석 비용을 줄입니다.

vendored ripgrep의 의미

이전 설명처럼 특정 번들러에 "내장된 embedded binary"로만 이해하면 좁습니다. 핵심은 런타임이 안정적으로 찾을 수 있는 vendored 실행 파일 경로를 확보하는 것입니다.

09

경로 안전성, 상대 경로화, UNC 보호

검색 결과는 보통 작업 디렉터리 기준 상대 경로로 줄여 토큰을 아낍니다. 하지만 모든 경로에 무조건 상대 경로화를 적용할 수는 없습니다. Windows UNC 경로나 다른 루트에 있는 경로는 잘못 줄이면 오히려 망가질 수 있기 때문입니다.

UNC 경로 보호

# 상대 경로화를 시도하되
candidate = relative(cwd, path)

# UNC나 다른 루트라면 원본을 유지
if unsafeRelative(candidate):
  use original path
딥 다이브 - 토큰 절약보다 경로 정확성이 먼저다

상대 경로는 토큰을 줄이지만, UNC나 다른 루트 경계를 잘못 다루면 경로 자체가 거짓 정보가 됩니다. 검색 도구는 여기서 절약보다 정확성을 우선합니다.

10

성능 아키텍처

검색 도구는 빠르기만 해서는 안 됩니다. 긴 줄, huge result set, 느린 파일시스템, 스레드 자원 부족 같은 현실적인 문제를 함께 다뤄야 합니다.

11

핵심 요약

핵심 포인트

  • Glob과 Grep는 모두 ripgrep를 기반으로 하지만, 경로 검색과 내용 검색으로 역할이 나뉩니다
  • 기본 ignore 동작은 .gitignore 하나보다 넓고, VCS 메타데이터 디렉터리도 실질적으로 제외합니다
  • GrepTool의 include는 shell 확장이 아니라 내부 glob 파싱을 거쳐 안전하게 ripgrep 인수로 전달됩니다
  • leading-dash 패턴은 옵션처럼 오인되지 않도록 인수 경계를 명확히 둡니다
  • vendored ripgrep는 배포물에 포함된 안정적 실행 파일 경로를 뜻하며, 특정 번들러에만 묶인 개념이 아닙니다
  • 경로 상대화는 토큰을 절약하지만, UNC나 다른 루트에서는 원본 경로를 유지해 정확성을 지킵니다
  • 결과 제한, 긴 줄 제한, 재시도, 타임아웃이 검색 도구의 현실적인 안정성을 만듭니다
12

지식 확인

퀴즈 - 5문제

Q1. 검색 도구의 기본 ignore 동작에 대한 설명으로 맞는 것은?

  • A) .gitignore만 본다
  • B) VCS ignore, 추가 ignore 파일, 숨김 경로 기본 정책을 함께 고려한다
  • C) 어떤 ignore도 적용하지 않는다
  • D) 바이너리 파일만 제외한다
ripgrep 기반 검색은 .gitignore 하나만 보지 않습니다. 여러 ignore 계층과 숨김 파일 기본 정책이 함께 작동합니다.

Q2. GrepTool의 include를 별도 파싱하는 이유는?

  • A) 정규식을 glob으로 바꾸기 위해
  • B) 검색 결과를 더 많이 얻기 위해
  • C) shell 확장 의존을 피하고 glob 패턴을 안전하고 일관되게 ripgrep에 넘기기 위해
  • D) VCS 디렉터리를 강제로 포함하기 위해
내부 파싱을 거치면 패턴 의미를 런타임이 통제할 수 있고, shell 차이에 흔들리지 않습니다.

Q3. leading-dash 패턴 안전장치가 필요한 이유는?

  • A) 검색 속도를 높이기 위해
  • B) 패턴이 ripgrep 옵션으로 오인되지 않게 하기 위해
  • C) 결과를 알파벳순으로 정렬하기 위해
  • D) UNC 경로를 짧게 만들기 위해
-foo 같은 입력은 옵션처럼 보일 수 있습니다. 패턴은 데이터로 취급되어야 하므로 인수 경계를 분명히 해야 합니다.

Q4. vendored ripgrep를 가장 잘 설명한 것은?

  • A) 시스템 PATH에서 찾은 첫 번째 rg
  • B) 특정 번들러 안에만 들어 있는 전용 바이너리
  • C) 배포물과 함께 제공되어 런타임이 안정적으로 찾을 수 있는 ripgrep 실행 파일
  • D) 네트워크에서 실행 시마다 다운로드하는 임시 바이너리
핵심은 앱이 의존 가능한 ripgrep 실행 파일을 함께 배포해 환경 차이를 줄인다는 점입니다.

Q5. UNC 경로 보호의 목적은 무엇인가요?

  • A) 상대 경로화가 경로 의미를 깨뜨릴 수 있는 네트워크 경로나 다른 루트 경계에서는 원본 경로를 유지하기 위해
  • B) VCS 디렉터리를 포함하기 위해
  • C) binary search를 가능하게 하기 위해
  • D) 결과 수를 250개로 제한하기 위해
토큰 절약보다 경로 정확성이 먼저입니다. UNC나 다른 루트의 경로를 잘못 상대화하면 거짓 경로가 됩니다.
0 / 5