


모든 코드 예제가 테스트되는 문서 책을 관리한다
코드 예제가 컴파일되고 테스트되는 문서 책을 고칠 때 쓴다. 빌드와 테스트 명령, 예제를 두는 두 가지 방법, 공유 라이브러리 버전을 올리지 않고 예제를 따로 옮기는 방법, 리뷰 전 체크리스트를 알려 준다.
이 AI 규칙을 사용하려면
## 책의 코드 블록을 그냥 글이 아니라 테스트되는 코드로 다룬다
이 책은 코드 블록이 삽입된 마크다운 파일로 작성된 실용적인 예제들의 모음이다. 문서 테스트 하네스가 소스 트리를 훑으며 모든 코드 블록을 추출해 컴파일하고 실행하므로, 깨진 예제는 깨진 애플리케이션 코드와 똑같이 빌드를 실패시킨다.
### 그것이 모든 수정에 뜻하는 바
컴파일되지 않는 예제는 문서가 아니다. 산문은 자유롭게 다시 표현해도 되지만, 코드 블록 안의 모든 변경은 테스트되는 소스에 대한 변경이므로 제안하기 전에 반드시 테스트 명령으로 실행해 봐야 한다.
### 렌더링된 책과 테스트 대상 범위를 어긋나지 않게 유지한다
같은 마크다운이 렌더링된 책과 테스트 하네스 양쪽에 공급되므로, 서식 선택이 곧 의미를 지닌다. 코드 블록에 붙은 주석(annotation)이 하네스가 그 블록을 어떻게 다룰지 결정하고, 독자에게 숨겨진 줄도 여전히 컴파일된다. 렌더링된 페이지를 더 깔끔해 보이게 하려는 이유만으로 주석이나 숨겨진 줄을 절대 제거하지 마라.
## 정해진 명령으로 책을 빌드하고, 테스트하고, 미리 본다
즉석에서 만들어 낸 호출 방식 대신 문서화된 명령을 통해 모든 일상 작업을 처리하여, 로컬 실행이 지속적 통합과 일치하게 한다.
### 중요한 명령들
- 마크다운 소스로부터 책을 빌드한다.
- 문서 테스트와 맞춤법 검사 단계를 합친 전체 스위트를 실행한다.
- 코드 블록을 변경했고 빠른 반복 루프를 원할 때는 문서 테스트 타깃만 실행한다.
- 산문을 편집하는 동안 라이브 리로드와 함께 책을 로컬에서 서빙한다.
- 리뷰 전 기본값으로 빌드와 테스트를 함께 실행한다.
- 링크 검사기를 실행한다. 이 도구는 저장소에 체크인된 설정 파일을 기준으로 내부 링크와 외부 링크를 검증한다.
- 맞춤법 검사 스크립트를 대화형으로 실행하고, 정당한 새 단어는 저장소의 사전 파일에 추가하여 그 추가분이 해당 변경과 함께 리뷰되게 한다.
### 툴체인을 고정한다
책 생성기와 링크 검사기는 문서화된 단일 설치 명령을 통해 정확히 고정된 버전으로 설치된다. 실패를 우회하려고 로컬에서 도구를 업그레이드하지 마라. 버전이 어긋나면 재현 가능한 실패가 당신에게만 보이는 실패로 바뀌기 때문이다.
## 예제를 두는 두 가지 방법을 알고, 공유 라이브러리 버전은 올리지 않는다
예제는 두 가지 방식 중 하나로 테스트되며, 어떤 파일이 어떤 패턴을 쓰는지 아는 것이 그 코드와 의존성이 어디에 놓이는지를 결정한다.
### 패턴 1: 제자리에서 테스트되는 인라인 블록
코드 블록이 소스 트리 아래 마크다운 안에 그대로 들어 있다. 빌드 스크립트가 그 트리에서 마크다운 파일을 훑어 코드 블록마다 테스트를 하나씩 생성한다. 그런 예제에 필요한 모든 의존성은 루트 매니페스트에 이미 존재해야 한다. 블록은 언어 에디션을 지정하는 주석과 compile-only, expected-panic, skip 같은 동작을 지정하는 주석을 받는다. 독자에게 필요 없는 보일러플레이트는 해시 기호와 공백을 앞에 붙인 줄로 작성하며, 하네스는 그 줄을 컴파일하지만 렌더링된 책은 숨긴다. 이것은 레거시 패턴으로, 동작은 유지하되 확장하지는 않는다.
### 패턴 2: 마크다운에 포함되는 독립 패키지
코드가 공유 코드 디렉터리 아래 자체 매니페스트를 가진 자기 자신의 패키지 안에 있고, 마크다운은 상대 경로로 소스 파일을 가리키는 include 지시자를 통해 그것을 끌어온다. 줄 범위 include를 쓰면 페이지가 파일의 일부만 보여줄 수 있는데, 이것이 테스트용 스캐폴딩을 렌더링된 예제 바깥에 두는 방법이다. 해당 경로는 빌드 스크립트에서 문서 테스트 하네스의 대상에서 제외되므로 코드가 두 번 테스트되지 않는다. 이것이 새로 만드는 예제와 마이그레이션한 예제에 권장되는 패턴이다.
### 의존성 규칙
루트 매니페스트에서 의존성 버전을 바꾸지 마라. 루트 매니페스트는 모든 인라인 예제가 공유하므로, 한 페이지를 만족시키려는 버전 올리기가 다른 수십 개를 조용히 망가뜨릴 수 있다. 어떤 예제에 더 새로운 의존성이 필요하다면, 그 대신 그 예제를 자체적으로 버전을 고정한 독립 패키지로 마이그레이션하라.
## 새 라이브러리가 필요한 예제는 자기 패키지로 옮긴다
의존성 버전을 바꿔야 할 때는 영향을 받는 예제들을 독립 패키지로 변환한다. 각 단계가 저장소를 다음 단계가 의존하는 상태로 남기므로, 순서대로 따라가라.
1. 공유 코드 디렉터리 아래에, 카테고리 이름 다음에 예제 이름이 오는 폴더로 자체 매니페스트를 가진 패키지를 만든다. 가능한 경우 공유 의존성은 워크스페이스에서 상속하고, 애초에 갈라놓는 것이 목적인 경우에는 버전을 독립적으로 고정한다.
2. 코드를 마크다운 코드 블록에서 패키지 소스로 옮긴다. 실행 가능한 예제 하나당 바이너리 하나, 또는 라이브러리 형태의 예제라면 라이브러리 모듈로 옮긴다.
3. 루트 매니페스트의 워크스페이스 멤버 목록에 그 패키지를 등록한다.
4. 마크다운 안의 인라인 코드를, 마크다운 파일 자신의 위치에서 패키지 소스까지 이어지는 상대 경로를 가진 include 지시자로 교체한다.
5. 빌드 스크립트에서 마이그레이션한 경로를 문서 테스트 하네스의 대상에서 제외한다. 제외 목록은 두 개인데, 하나는 디렉터리 접두사를 받아 그 아래 전부를 제거하고, 다른 하나는 마크다운 파일 하나를 받는다. 상황에 맞는 더 좁은 쪽을 써라.
6. 양쪽 모두를 테스트한다. 새 패키지 자체의 테스트를 실행하고, 문서 테스트 타깃을 다시 실행해 블록을 없앤 것이 남아 있는 인라인 예제들을 망가뜨리지 않았는지 확인한다.
5단계 전에 멈춘 마이그레이션은 예제를 두 번 컴파일되는 상태로 남기고, 6단계 전에 멈춘 마이그레이션은 조용히 커버리지를 잃을 수 있다.
## 무엇을 빌드하고 테스트할지 정하는 파일을 읽는다
무엇이 테스트되고, 무엇이 렌더링되며, 어떤 명령이 존재하는지를 소수의 파일이 결정한다. 동작을 바꾸기 전에 그 파일들을 읽고, 의도를 가지고 바꿔라.
- 루트 매니페스트는 인라인 예제가 쓰는 의존성과 워크스페이스 멤버 목록을 담는다.
- 빌드 스크립트는 문서 테스트 하네스를 위해 마크다운을 찾아내고, 마이그레이션한 예제가 두 번 테스트되지 않게 하는 두 개의 제외 목록을 지닌다.
- 책 설정 파일은 마크다운이 책으로 어떻게 렌더링되는지를 제어한다.
- 빌드 도구 설정은 문서화된 명령들이 의존하는 태스크 러너 별칭을 정의한다.
- 태스크 러너 패키지는 빌드, 테스트, 링크 검사를 하위 명령으로 구현하여, 같은 로직이 기여자와 지속적 통합 양쪽에 쓰이게 한다.
어떤 명령이 여기 적힌 설명과 다르게 동작한다면, 위의 파일들을 진실의 근원으로 간주하고 우회하지 말고 설명 쪽을 고쳐라.
## 독자가 복사해서 바로 실행할 수 있는 완전한 예제를 쓴다
예제는 페이지에서 얼마나 짧아 보이는지가 아니라, 누군가 자기 프로젝트에 복사해 넣었을 때 동작하는지로 평가된다.
### 내용 규칙
- 예제는 조각이 아니라 완전하고 컴파일 가능한 것이어야 한다.
- 실패 시 패닉을 일으키는 대신 해당 언어의 오류 전파 연산자로 오류를 전파하고, 프로젝트에 문서화된 오류 처리 패턴을 따른다.
- 글롭 임포트를 피해서, 독자가 예제가 의존하는 트레이트와 항목을 정확히 볼 수 있게 한다.
- 외부 서비스나 네트워크 접근이 필요한 예제는 compile-only로 표시하여, 스위트가 오프라인에서도 실행 가능한 상태로 유지되게 한다.
- 보일러플레이트는 삭제하지 말고 숨김 줄 접두사로 숨겨서, 예제가 여전히 컴파일되게 한다.
- 새 예제를 위해 루트 매니페스트에 의존성을 하나 더 추가하기보다 독립 패키지를 만드는 쪽을 택한다.
### 새 최상위 섹션 추가하기
새 최상위 섹션 페이지를 추가할 때는, 책의 목차 페이지에도 그것에 대한 include를 올바른 알파벳 순 위치에 함께 추가한다. 그 페이지가 독자의 진입점이므로, 거기에 포함되지 않은 섹션은 빌드가 성공하더라도 사실상 보이지 않는 것이나 다름없다.
## 리뷰를 요청하기 전에 모든 테스트와 체크리스트를 통과한다
리뷰를 위해 변경을 올리거나 갱신하기 전에, 그리고 다시 쓸 때마다 그 뒤에, 다음을 전부 확인한다.
- 부분 실행이 아니라 문서화된 전체 테스트 명령을 써서 전체 테스트 스위트가 로컬에서 통과한다.
- 커밋들이 하나로 스쿼시되어 있고 최신 main 브랜치 위에 리베이스되어 있다.
- 설명에 올바른 이슈 종료 절이 들어 있거나, 해당 이슈가 없다면 그 절이 통째로 제거되어 있다. 잘못된 이슈 번호는 아예 없는 것보다 나쁘다.
- 렌더링되지 않는 목록은 정렬된 순서로 되어 있다: 링크, 참조, 식별자, 매니페스트 항목. 정렬된 순서가 앞으로의 diff를 작게 유지해 준다.
- 외부 API 레퍼런스 페이지로 향하는 문서 링크는 고정된 버전 대신 와일드카드 버전 구간을 쓰므로, 다음 릴리스에서 링크가 썩지 않는다.
- 예제는 프로젝트의 표준 오류 처리를 사용하며, 실패 시 패닉으로 때우는 지름길이 없다.
- 설명 안의 코드 식별자는 백틱으로 감싼 이름으로 쓰고, 파일 하단의 링크 정의를 통해 각자의 레퍼런스 페이지로 하이퍼링크되어 있다.
제출한 뒤에는 지속적 통합 실행을 지켜보고, 빨간 상태의 변경을 리뷰어가 분류하도록 열어 둔 채 두지 말고 보고된 실패를 직접 고쳐라.
