Make your blogs run!
Tags: unison, alphatest, markdown
Published: 2020-01-05 18:05:17

[`Unison`](https://www.unisonweb.org/) comes with a convenient way of reproducing user interactions with `ucm` for all intents and purposes.

Originally not aware of transcripts, I started writing the odd `Unison` blog the hard way, that is, text in one location, code snippets and output being copy-pasted. The 1980s way of doing things worked out for a lot of people after all. Turns out, if you're working with markdown to begin, graduation to transcripts is not that far off.

##### So what are `unison transcripts`?

Transcripts are markdown files with a twist. They mix in blocks of `Unison` code, to be typechecked by `ucm`, and blocks of commands, to be run by `ucm`.

The input-transcript can be orchestrated in such a way that markdown text as well as `unison` and `ucm` blocks are interleaved to produce output that is ready for consumption by third parties.

##### What are the pros?

As mentioned, you can formulate your interaction with `ucm` in a detailed and documented manner, with comments and explanations to pinpoint specifically for example what the exact requirements are to reproduce a bug or failure.

No time wasted explaining, just share the transcript, which in effect acts as an integration test. If something is wrong with `ucm`, a fix followed by a passing run means the fix holds. (And the unison code base does indeed follow this approach currently).

Being `markdown` files, you can use your editor of choice, and the formatting rules you are (potentially) already familiar with.

##### What are the cons?

Depending on the circumstances, certain aspects of reproducing a whole environment (beginning with a couple of heavy `git pulls` for example) might mean that the process can become slow and maybe bloated. 

If your main aim is to share code in general, transcripts cannot replace a code repository.

Also, each transcript runs in its own sandbox, so cleanup of the sandboxed checkouts will be required afterwards.

##### How does it work in practice?

`ucm` outputs the regular markdown of the transcript directly to the output file, until it finds specific `fenced` blocks (as per the example that follows). These blocks are translated as `ucm` commands (`pull` from github, `test`, `add`, `update` and all the usual suspects), or `unison` code to be typechecked.

`ucm` blocks containing commands are issued to a sandboxed `ucm` and `unison` blocks are typechecked in the same sandbox for correctness. You can emulate the `unison` blocks to run in the context of a specific file.

##### Can I play too?

All you need is:
* the Unison codebase manager [`ucm`](https://github.com/unisonweb/unison/releases). Optionally in the `$PATH`.
* an editor of your choice edit the transcript in.

You need be able to run `ucm` and point it to a transcript. Name the transcript `example.md`, and when ready, run: `ucm transcript example.md`. 

##### Where do we start?

A number of examples come with the [`Unison codebase`](https://github.com/unisonweb/unison/tree/master/unison-src/transcripts), [`hello`](https://github.com/unisonweb/unison/blob/master/unison-src/transcripts/hello.md) being the one I used as a guide.

For the curious: you might want to look into what happens during the `stack exec tests` build step when compiling `Unison` from source.

##### What is a "minimum viable transcript"?

Technically, an empty markdown file, although that would not really be of much use to you. So here's an example of content that contains a `unison` and a `ucm` block.

    ```unison
    str = "hello"
    ```
Once the above block is typechecked, a `ucm` block can issue commands that operate on the previous code block.

    ```ucm
    .> add
    .> view str
    .> undo
    ```

To sum up: a transcript with the above two blocks will create a sandboxed checkout, then typecheck the `unison` block, then run the `ucm` commands. 

Here is the output of `ucm` after processing the transcript successfully.

```
ucm transcript example.md

  Transcript will be run on a new, empty codebase.

  ⚠️
  
  Initializing a new codebase in:
  /.../transcript-75f55eaeebee4386

   _____     _             
  |  |  |___|_|___ ___ ___ 
  |  |  |   | |_ -| . |   |
  |_____|_|_|_|___|___|_|_|
  
  Running the provided transcript file...
  

⚙️   Processing stanza 2 of 2.
💾  Wrote /.../unison/example.output.md

  🌸
  
  I've finished running the transcript(s) in this codebase:
  
    /.../transcript-75f55eaeebee4386
  
  You can run
  `ucm -codebase /.../transcript-75f55eaeebee4386`
  to do more work with it.
```

`ucm` even provides you with the next command to run, in order to continue interactively, from where the transcript concluded.


Hope you find transcripts useful!

##### Thanks!
I must at this point thank [`Arya Irani`](https://github.com/aryairani), for reviewing this post for syntax, grammar and spelling errors.