Transcripts는 Unison 코드와 Unison Codebase Manager(UCM)의 상호작용을 스크립트 형태로 기술하는 방법을 제공한다. 이 문서는 transcript의 구성 요소, 실패 기대 선언, 출력 숨기기, 상태를 가지는 stanza, 코드베이스 옵션 등을 설명한다.
Transcripts는 Unison 코드와 Unison Codebase Manager(UCM) 사이의 상호작용을 스크립트로 작성하는 방법을 제공한다. Transcript는 fenced 코드 블록을 포함하는 마크다운 문서로 작성하며, 이 코드 블록 안에 실행할 Unison 코드와 UCM 명령을 정의한다.
📑
이 문서에서 다루는 내용
Transcript 파일은 여러 개의 상호작용으로 구성된 .md 파일이며, 각 상호작용을 "stanza"라고 부른다. Stanza들은 파일의 맨 위에서부터 아래 방향으로 순서대로 평가된다.
Transcript 안에서 Unison 코드를 작성할 때는, 세 개의 백틱 다음에 unison을 붙여 코드 블록을 시작한다.
text``` unison myTerm = "Hello world"
이제 이 term 을 Unison 코드베이스에 추가하고 싶다고 하자. 이것을 세 개의 백틱 다음에 `ucm`이라는 단어를 붙인 fenced 코드 블록으로 기술할 수 있다.
```text
``` ucm
scratch/main> add myTerm
`scratch/main>`는 프롬프트 표시로, 왼쪽에는 프로젝트/브랜치 표시를, 오른쪽에는 UCM 명령을 구분하기 위해 사용한다. 지정한 프로젝트와 브랜치는 존재하지 않을 경우 자동으로 생성된다. `scratch/main`은 transcript에서 사실상의 표준 이름이다. 프롬프트의 오른쪽에는 코드베이스와 상호작용하기 위한 UCM 명령을 입력할 수 있다.
UCM을 시작할 때 transcript를 실행하려면, `transcript` 옵션과 함께 마크다운 파일 경로를 다음과 같이 넘기면 된다.
```bash
ucm transcript path/to/transcript.md
기본적으로 transcript는 매번 새 코드베이스에 대해 실행된다. Transcript를 실행하면, 새로운 코드베이스를 담기 위한 임시 디렉터리를 만들었다가, 실행이 끝나면 삭제한다. 주의할 점은, UCM을 codebase-create 인자로 초기화할 때와는 달리, transcript에서 초기화되는 코드베이스에는 base 라이브러리가 포함되지 않는다는 것이다. Transcript는 보통 맨 처음에 ``` ucm 블록을 하나 두고, 그 안에서 builtins.merge 명령을 실행하여 최소한의 builtin 집합을 불러오도록 시작한다 (Nat, List 같은 것들).
비슷하게, builtins.mergeio 명령은 IO를 지원할 수 있는 Unison builtin 집합을 불러온다.
text``` ucm :hide scratch/main> builtins.merge
만약 `base` 라이브러리가 스코프에 잡힌 코드베이스를 transcript에서 사용하고 싶다면, 원하는 `base` 라이브러리에 대해 `lib.install` 명령을 실행하는 `ucm` 블록을 추가하면 된다.
또한, transcript 안에서 `base`를 설치하면 실행 시간이 몇 초가 더 걸릴 수 있으니, 차 한 잔을 준비할 마음의 여유를 가지는 것이 좋다. 🫖
Transcript가 성공적으로 실행되면, UCM은 transcript에서 기술한 상호작용의 결과를 담은 출력 파일을 생성한다. Transcript 실행 결과 출력은 원본과 같은 이름과 경로에 `.output` 접미사가 붙은 파일로 기록된다.
👉
알고 있었는가? Transcript는 프로젝트 유지보수자가 버그를 분류하고 고치는 데 도움을 줄 수 있다! 재현 절차를 transcript로 작성해서, 그 마크다운 파일을 버그 리포트에 첨부하면 된다.
---
## Expecting failures
어떤 stanza가 실패할 것임을 알리는 방법은 두 가지가 있다. `:error` 태그와 `:bug` 태그이다. 이 태그들은 버그 티켓을 만들 때, 에러가 예상된 것인지, 아니면 예상치 못한 것인지를 전달하는 데 유용하다.
Fenced 코드 블록에 `:error` 태그를 추가하면, UCM이 그 블록을 실행할 때 실패할 것으로 예상해야 한다는 의미가 된다.
```text
``` ucm :error
scratch/main> add failureExpected
`:error`는 transcript 실행기가 이후의 stanza들을 계속해서 실행하도록 해 준다.
Unison stanza가 **성공해야 하는데 실패**하는 경우를 나타내려면, fenced 코드 블록에 `:bug` 태그를 추가하라.
```text
``` ucm :bug
scratch/main> add shouldSucceed
반대로, stanza가 **실패해야 한다고 생각했는데 실제로는 성공**할 때를 보고하려면, 두 태그를 함께 사용하여 `:error :bug`처럼 적는다.
```text
``` unison :error :bug
aTerm = "imagine this should fail but succeeds mysteriously"
---
## Hiding output
어떤 상호작용의 출력이 너무 장황해서 `.output` 파일에 포함하고 싶지 않은 경우, 어떤 stanza에도 `:hide` 수식어를 붙여서 숨길 수 있다.
```text
``` ucm :hide
scratch/main> builtins.merge
unisonscratch/main> List.range 0 99
`:hide`가 붙은 stanza의 출력은 transcript 출력 파일에 포함되지 않는다.
---
## Stateful stanzas
상황에 따라, transcript의 stanza들이 UCM과 scratch 파일 사이의 일종의 상호 편집(back-and-forth) 상호작용을 포함할 수도 있다. 예를 들어, 어떤 버그가 **최초 타입체킹 시에는 발생하지 않지만, 수정된 term을 업데이트할 때만** 드러나는 경우가 있다. 이를 재현하려면 해당 term을 `edit`해야 하는데, 기본적으로 stanza들은 "다시 연" Unison term의 상태를 반영하지 않는다.
Transcript 코드베이스에 term을 저장하고 수정해야 할 필요가 있다면, UCM의 [`edit`](https://www.unison-lang.org/docs/ucm-commands/edit) 명령을 사용해 `scratch.u` 파일을 열고 그 안에 term을 렌더링할 수 있다. 그런 다음, `load` 명령으로 이 파일을 다시 transcript 코드베이스의 스코프로 가져와, term을 편집하는 상호작용을 흉내 낼 수 있다.
```text
``` unison
myTerm = "hi"
ucmscratch/main> add myTerm scratch/main> edit myTerm
이 시점에서 scratch.u 파일의 맨 위에는 myTerm 정의가 들어 있다.
text``` ucm scratch/main> load scratch.u
unisonmyTerm = "hi there!"
이러한 방식으로, transcript 안에서 term을 수정하고 다시 불러오는 과정을 단계별로 재현할 수 있다.
---
## Transcript codebase options
기본적으로 transcript는 매번 새로운, 일시적인 코드베이스에 대해 실행되지만, transcript가 실행될 코드베이스와 실행 후 결과 코드베이스를 어떻게 처리할지 제어하는 여러 옵션이 존재한다.
**명령** | **입력 코드베이스** | **출력 코드베이스**
---|---|---
```bash
ucm transcript \
./transcript.md
``` | 새로운, 임시 코드베이스 | 실행 후 삭제됨
```bash
ucm transcript \
./transcript.md \
--save-codebase
``` | 새로운 코드베이스 | 실행 결과 코드베이스의 새 복사본을 저장함
```bash
ucm transcript \
./transcript.md \
--save-codebase-to ./aCodebase
``` | 새로운 코드베이스 | 지정된 기존 코드베이스를 갱신함. 주의해서 사용할 것!
```bash
ucm transcript.fork \
./transcript.md \
--codebase ./aCodebase
``` | 인자로 주어진 기존 코드베이스의 복사본 | 새로운 코드베이스를 출력으로 생성; 원본 코드베이스는 변경되지 않음
```bash
ucm transcript.in-place \
./transcript.md \
--codebase ./aCodebase
``` | 기존 코드베이스 | 지정된 코드베이스를 직접(in-place) 수정함. 주의해서 사용할 것!
원하지 않는 코드베이스 변경을 되돌리고 싶은가? [코드베이스 상태를 되돌리기 위해 `reflog`와 `reset` 명령을 사용](https://www.unison-lang.org/docs/usage-topics/resetting-codebase-state)하라.
---
## UCM
"UCM"은 "Unison Codebase Manager"의 약자이다. 이는 Unison 코드베이스를 탐색하고 수정하며, Unison 프로그램을 실행하는 데 사용하는 일체형 도구이다.
### lib.install
지정한 라이브러리의 최신 릴리스를 다운로드한다.
```text
myProject/main> lib.install @unison/base
특정 버전의 라이브러리를 설치하려면, 라이브러리 이름 뒤에 releases/versionNumber를 붙여 사용한다.
textmyProject/main> lib.install @unison/base/releases/1.0.0
lib.install 명령은 Unison 0.5.21 버전부터 Unison Share에서 라이브러리를 설치하는 데 사용된다. 더 오래된 Unison 버전을 사용 중이라면, 라이브러리를 설치하기 위해 pull 명령을 사용해야 한다.
© 2025