
# 시작하기

## 설치

Composer을 통해 Greph을 설치하세요.

```bash
composer require greph/greph
```

이렇게 하면 라이브러리와 네 가지 실행 파일이 `vendor/bin/`에 설치됩니다.

- `greph`: 네이티브 텍스트 검색, AST 검색 및 AST 재작성
- `greph-index`: 워밍된 텍스트 인덱스, AST 팩트 인덱스 및 캐시된 AST 검색
- `rg`: ripgrep 스타일 호환 래퍼
- `sg`: ast-grep 스타일 호환 래퍼

Greph 0.2.3하기 때문에 이 실행 파일은 프로젝트의 `vendor/bin/`에서 작동합니다. 이전 릴리스에서는 Greph 저장소의 복제본 안에 있는 Composer 오토로더만 찾았으므로, 해당 버전 이상을 사용해야 합니다.

```bash
composer require greph/greph:^0.2.3
```

## 요구 사항

- **PHP 8.2+** readonly 클래스, enum, first-class callable 구문, 생성자 프로모션 지원
- **ext-json** JSON 출력 및 디스크 인덱스 페이로드용
- **ext-ctype** 패턴 및 옵션 파싱용
- **ext-tokenizer** PHP-Parser 및 AST 사전 필터용
- **ext-zlib** 캐시된 AST 저장소(`greph-index ast-cache`)용
- **nikic/php-parser** (Composer 종속 항목으로 자동 설치됨)

`ext-json`, `ext-ctype`, `ext-tokenizer`는 거의 모든 PHP 빌드에서 활성화되어 있습니다. 현재 `composer.json`는 `ext-json`만 선언하므로([#5](https://github.com/inline0/greph/issues/5)), 다른 항목 중 하나가 없어도 Composer는 경고하지 않습니다.

선택 사항:

- 병렬 스캔에는 **ext-pcntl**이 필요합니다. Greph가 없으면 단일 프로세스 실행으로 원활하게 전환됩니다.
- 벤치마크 비교를 위한 외부 `rg`, `grep`, `sg` 바이너리입니다. 런타임에는 필요하지 않습니다.

검색, 재작성 및 인덱싱 과정에서는 `proc_open()` 또는 `shell_exec()`를 호출하지 않습니다. 병렬 스캔만 프로세스를 분기하며, `pcntl_fork()`가 없으면 단일 프로세스로 대체 실행됩니다. `proc_open()`, `shell_exec()` 또는 `pcntl_fork()`를 비활성화하는 호스트는 [프로세스 제한 호스트](https://greph.inline0.dev/ko/docs/advanced/process-restricted-hosts)를 참조하세요.

## 첫 텍스트 검색

Greph의 기본 모드는 grep 호환 텍스트 검색입니다:

```bash
vendor/bin/greph -F "function" src
```

출력은 grep, ripgrep 및 대부분의 편집기 통합 기능이 기대하는 표준 `file:line:content` 형식을 사용합니다.

```text
src/Greph.php:41:    public static function walk(string|array $paths, ?WalkOptions $options = null): FileList
src/Greph.php:50:    public static function searchText(string $pattern, string|array $paths, ?TextSearchOptions $options = null): array
src/Greph.php:81:    public static function buildTextIndex(
```

대소문자를 구분하지 않는 일치는 `-i`, 전체 단어 일치는 `-w`, 개수 표시에는 `-c`, 파일 경로만 표시하려면 `-l`, 앞뒤 두 줄의 컨텍스트를 표시하려면 `-C 2` 등을 추가하세요. 전체 목록은 [참조CLI에서 확인할 수 있습니다.](https://greph.inline0.dev/ko/docs/cli)

## 첫 AST 검색

구조 검색으로 전환하려면 `-p`와 PHP 형태의 패턴을 전달하세요:

```bash
vendor/bin/greph -p 'new $CLASS()' src
```

`$CLASS`는 모든 클래스 이름을 캡처하는 메타변수입니다. `new $CLASS()` 패턴은 클래스나 서식, 주석에 관계없이 인수가 없는 모든 `new` 식과 일치합니다. 인수가 무엇이든 호출과 일치시키려면 `new $CLASS($$$ARGS)`를 사용하세요.

각 AST 일치 항목은 파일, 시작 줄, 일치한 코드 순으로 출력됩니다:

```text
src/Greph.php:43:new FileWalker()
src/Greph.php:52:new TextSearchOptions()
src/Greph.php:54:new TextSearcher()
```

그 밖의 유용한 패턴:

```bash
# Any method call with any arguments
vendor/bin/greph -p '$obj->$method($$$ARGS)' src

# Any function declaration with a void return type
vendor/bin/greph -p 'function $name($$$PARAMS): void {}' src

# Old-style array calls
vendor/bin/greph -p 'array($$$ITEMS)' src
```

전체 패턴 구문은 [모드 / AST 검색](https://greph.inline0.dev/ko/docs/modes/ast)을 참조하세요.

## 첫 재작성

AST 검색을 재작성으로 전환하려면 `-r`를 추가하세요:

```bash
# Preview only
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --dry-run src

# Apply
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' src

# Confirm each file before writing
vendor/bin/greph -p 'array($$$ITEMS)' -r '[$$$ITEMS]' --interactive src
```

재작성은 일치 항목 바깥의 서식을 유지합니다. 일치한 노드만 교체되며 주변 공백, 들여쓰기, 주석은 그대로 유지됩니다. 일치한 노드 자체는 템플릿에서 새로 출력되므로 내부 레이아웃이 정규화되고, 노드 안의 주석은 사라질 수 있습니다. 자세한 내용은 [모드 / 재작성](https://greph.inline0.dev/ko/docs/modes/rewrite)을 참조하세요.

## PHP API

정적 `Greph\Greph` 파사드는 CLI와 같은 작업을 제공합니다:

```php
use Greph\Greph;
use Greph\Ast\AstSearchOptions;
use Greph\Text\TextSearchOptions;

$results = Greph::searchText(
    'function',
    'src',
    new TextSearchOptions(fixedString: true, caseInsensitive: true),
);

foreach ($results as $file) {
    foreach ($file->matches as $match) {
        echo "{$file->file}:{$match->line}:{$match->content}\n";
    }
}

$matches = Greph::searchAst(
    'new $CLASS()',
    'src',
    new AstSearchOptions(),
);

foreach ($matches as $match) {
    echo "{$match->file}:{$match->startLine}:{$match->code}\n";
}
```

전체 기능은 [API](https://greph.inline0.dev/ko/docs/api)에서 다룹니다.

## 인덱스 검색

반복 작업은 미리 준비된 인덱스를 활용하면 빨라집니다. 한 번 빌드한 다음 여러 번 쿼리하세요:

```bash
# Text index
vendor/bin/greph-index build .
vendor/bin/greph-index search -F "function" .

# AST fact index
vendor/bin/greph-index ast-index build .
vendor/bin/greph-index ast-index search 'new $CLASS()' src

# Cached parsed-tree index
vendor/bin/greph-index ast-cache build .
vendor/bin/greph-index ast-cache search 'array($$$ITEMS)' src
```

기본적으로 인덱스는 프로젝트 루트의 `.greph-index`, `.greph-ast-index`, `.greph-ast-cache`에 저장됩니다.

자주 변경되는 트리에서는 미리 준비된 인덱스를 모두 똑같이 취급하는 대신 수명 주기 프로필을 선택하세요:

```bash
vendor/bin/greph-index build . --lifecycle static
vendor/bin/greph-index build . \
  --lifecycle opportunistic-refresh \
  --auto-refresh-max-files 32 \
  --auto-refresh-max-bytes 1048576
vendor/bin/greph-index stats . --dry-refresh
```

일반적인 패턴은 다음과 같습니다:

- 안정적인 기준 인덱스는 `static`로 유지
- 자주 변경되는 오버레이는 `opportunistic-refresh`로 유지
- 오래된 상태의 동작은 `stats --dry-refresh`로 검사

### 여러 인덱스를 사용한 검색

한 명령으로 미리 준비된 여러 인덱스를 검색할 수 있습니다:

```bash
vendor/bin/greph-index search -F "apply_filters" . \
  --index-dir wordpress/.greph-index \
  --index-dir wp-content/plugins/my-plugin/.greph-index \
  --show-index-origin

vendor/bin/greph-index ast-index search 'new $CLASS()' . \
  --index-dir wordpress/.greph-ast-index \
  --index-dir wp-content/plugins/my-plugin/.greph-ast-index \
  --show-index-origin
```

### 이름이 지정된 인덱스 세트

이 작업을 반복한다면 구성을 `.greph-index-set.json`에 저장하고, 플래그를 반복해서 지정하는 대신 세트 하위 명령을 사용하세요:

```bash
vendor/bin/greph-index set build
vendor/bin/greph-index set stats --dry-refresh
vendor/bin/greph-index set search --show-index-origin -F "apply_filters" .
vendor/bin/greph-index set search --mode ast-index 'new $CLASS()' .
vendor/bin/greph-index set search --mode ast-cache 'array($$$ITEMS)' .
```

### 플래너 추적

미리 준비된 검색이 후보를 어떻게 좁히는지 보려면 `--trace-plan`를 추가하세요:

```bash
vendor/bin/greph-index search --trace-plan -F "function" .
vendor/bin/greph-index ast-index search --trace-plan 'new $CLASS()' .
```

전체 사전 준비 워크플로우는 [인덱스 / 텍스트](https://greph.inline0.dev/ko/docs/indexed/text) 및 [인덱스 / AST](https://greph.inline0.dev/ko/docs/indexed/ast)를 참조하세요.

## 호환성 래퍼

이미 ripgrep 또는 ast-grep를 사용하는 도구나 에이전트가 있다면 래퍼를 추가하세요:

```bash
vendor/bin/rg --json -F "function" src
vendor/bin/sg --pattern 'new $CLASS()' src --lang php
```

두 래퍼 모두 같은 엔진을 재사용하며 업스트림 바이너리를 대상으로 프로브 검증을 거쳤습니다. 검증된 기능은 [호환성 / rg](https://greph.inline0.dev/ko/docs/compatibility/rg) 및 [호환성 / sg](https://greph.inline0.dev/ko/docs/compatibility/sg)에 문서화되어 있고, 생성된 [기능 매트릭스](https://greph.inline0.dev/ko/docs/advanced/feature-matrix)에도 수록되어 있습니다.

## 구성

Greph는 디스크에 저장하는 두 가지 규칙을 따릅니다:

- 기본적으로 `.gitignore`를 따릅니다. 사용하지 않으려면 `--no-ignore`를 전달하세요.
- `.grephignore`는 `.gitignore`와 같은 구문을 사용해 그 위에 적용됩니다. 버전 관리에 포함하고 싶지 않은 도구별 제외 항목에 유용합니다.

선택한 루트의 기본 인덱스 디렉터리는 `.greph-index`, `.greph-ast-index`, `.greph-ast-cache`입니다. 모든 `greph-index` 하위 명령에서 `--index-dir`로 재정의하거나, 반복 가능한 다중 인덱스 구성에는 `.greph-index-set.json`를 사용하세요.
