Skip to main content

TEstable SHell sessions in Markdown

Project description

CI for tesh (main branch) Test coverage (main branch) Test coverage (main branch) latest version of tesh on PyPI Supported Python versions License: MIT Built by these great folks!

tesh [tɛʃ] - TEstable SHell sessions in Markdown

Showing shell interactions how to run a tool is useful for teaching and explaining.

Making sure that example still works over the years is painfully hard.

Not anymore.

$ tesh demo/
📄 Checking demo/happy.md
  ✨ Running foo  ✅ Passed
  ✨ Running bar  ✅ Passed
📄 Checking demo/sad.md
  ✨ Running foo  ❌ Failed
         Command: echo "foo"

         Expected:
sad panda
         Got:
foo

Taking you into the shell ...

Enter `!!` to rerun the last command.

$

Syntax

To mark a code block as testable, append tesh-session="NAME" to the header line.

You can use any syntax highlighting directive, such as bash, shell, shell-session, console or others.

```console tesh-session="hello"
$ echo "Hello World!"
Hello World!
```

Linking multiple code blocks into a single shell session

Besides marking a code block as testable, tesh-session is a unique identifier that allows for multiple code blocks to share the same session.

```console tesh-session="multiple_blocks"
$ export NAME=Earth

```
```console tesh-session="multiple_blocks"
$ echo "Hello $NAME!"
Hello Earth!
```

Ignoring parts of the output

Parts of the inline output can be ignored with ...:

```console tesh-session="ignore"
$ echo "Hello from Space!"
Hello ... Space!
```

Multiline support

The same can be done for multiple lines of output. Note that trailing whitespace in every line is trimmed.

```console tesh-session="ignore"
$ printf "Hello \nthere \nfrom \nSpace!"
Hello
...
Space!
```

Commands can continue across multiple lines by prefixing lines with > .

```console tesh-session="multiline"
$ echo "Hello from" \
>   "another" \
>   "line!"
Hello from another line!
```

Advanced directives

You can set a few other optional directives in the header line:

  • tesh-exitcodes: a list of exit codes in the order of commands executed inside the code block,
  • tesh-setup: a filename of a script to run before running the commands in the code block,
  • tesh-ps1: allow an additional PS1 prompt besides the default $,
  • tesh-platform: specify on which platforms this session block should be tested (linux, darwin, windows),
  • tesh-fixture: a filename to save the current snippet,
  • tesh-timeout: number of seconds before a command timeouts (defaults to 30s),
  • tesh-long-running: set to true to showcase long-running commands such as docker compose up.

Let's look at all of these through examples!

Testing exit codes

tesh-exitcodes accepts a list of integers, which represent the exit code for every command in the block.

```console tesh-session="exitcodes" tesh-exitcodes="1 0"
$ false

$ true

```

Test setup

Sometimes you need to do some test setup before running the examples in your code blocks. Put those in a file and point to it with the tesh-setup directive.

```console tesh-session="setup" tesh-setup="readme.sh"
$ echo "Hello $NAME!"
Hello Gaea!
```

Custom prompts

Every so often you need to drop into a virtualenv or similar shell that changes the prompt. tesh supports this via test-ps1 directive.

```console tesh-session="prompt" tesh-ps1="(foo) $"
$ PS1="(foo) $ "


(foo) $ echo "hello"
hello
```

Only run on certain platforms

Some examples should only run on certain platforms, use tesh-platform to declare them as such.

```console tesh-session="platform" tesh-platform="linux"
$ uname
...Linux...
```
```console tesh-session="platform" tesh-platform="darwin"
$ uname
...Darwin...
```

Dump file to disk

Occasionally your examples consist of first showing contents of a file, then executing a command that uses said file. This is supported, use the tesh-fixture directive.

```bash tesh-session="fixture" tesh-fixture="foo.sh"
echo "foo"
```
```console tesh-session="fixture"
$ chmod +x foo.sh

$ ./foo.sh
foo
```

Custom timeout

By default, tesh will fail if an example command does not finish in 30 seconds. This number can be modified using the tesh-timeout directive.

```console tesh-session="timeout" tesh-timeout="3"
$ sleep 1

```

Long running processes

Some processes that you want to show examples for are long-running processes, like docker compose up. They are supported in tesh blocks using the tesh-long-running directive. Note that they need to be the last command in the block.

```console tesh-session="long-running" tesh-timeout="1" tesh-long-running="true"
$ nmap 1.1.1.1
Starting Nmap ...
```

Installation

The best way to install tesh is with your favorite Python package manager.

$ pip install tesh

Design decisions

  • Supports Linux / macOS.
  • Not tied to a specific markdown flavor or tooling.
  • Renders reasonably well on GitHub.

Comparison with other tools

tesh mdsh pandoc filters
Execute shell session ✔️ ✔️ ✔️
Modify markdown file with the new output 🚧[1] ✔️ ✔️
Shared session between code blocks ✔️ ✖️ ✖️
Custom PS1 prompts ✔️ ✖️ ✖️
Assert non-zero exit codes ✔️ ✖️ ✖️
Setup the shell environment ✔️ ✖️ ✖️
Reference fixtures from other snippets ✔️ ✖️ ✖️
Wildcard matching of the command output ✔️ ✖️ ✖️
Starts the shell in debugging mode ✔️ ✖️ ✖️
Specify timeout ✔️ ✖️ ✖️
Support long-running commands ✔️ ✖️ ✖️
  • ✔️: Supported
  • C: Possible but you have to write some code yourself
  • 🚧: Under development
  • ✖️: Not supported
  • ?: I don't know.

Developing tesh

We provide two development environments for people working on this project, one based on Nix and one based on Docker.

For Nix, run nix develop to enter the development environment, where everything is ready for use.

For Docker, run docker build -t tesh . && docker run --rm -v .:/tesh -it tesh to enter the development environment, where everything is ready for use.

Then you can run make tests to run all tests & checks.

Additional make commands are available to run just a subset of tests or checks.

# run tesh on all Markdown files
$ make tesh

# run flake8 linters on changed files only
$ make lint

# run flake8 linters on all files
$ make lint all=true

# run mypy type checker
$ make types

# run unit tests
$ make unit

# run a subset of unit tests (regex find)
$ make unit filter=foo

Multiple Python versions

By default, the development environment uses the latest supported Python version. This is how you drop into an environment with an older Python

On Linux:

$ nix develop .#devShells.x86_64-linux.default-python39

On macOS:

$ nix develop .#devShells.aarch64-darwin.default-python39

On CI, all supported versions of Python are tested.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tesh-0.3.2.tar.gz (17.4 kB view details)

Uploaded Source

Built Distribution

tesh-0.3.2-py3-none-any.whl (20.1 kB view details)

Uploaded Python 3

File details

Details for the file tesh-0.3.2.tar.gz.

File metadata

  • Download URL: tesh-0.3.2.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.6

File hashes

Hashes for tesh-0.3.2.tar.gz
Algorithm Hash digest
SHA256 5026902b60a8b14967f549152f14c8bc97b2d8caec8bbd1b6662b91138142a5d
MD5 16e4c9383e1071d3e9fe3a68343565a3
BLAKE2b-256 df9772077590613900b6c2bebc4f37eb7608a59d14999a7ebf741877a2c8a4a1

See more details on using hashes here.

File details

Details for the file tesh-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: tesh-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 20.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.6

File hashes

Hashes for tesh-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a1e829d61f58afaf9450a3bb95ca2780e945771b881c3080ee4906778daf33df
MD5 6baab6a67dfa86c6b64100181c1cc889
BLAKE2b-256 42b3762bb6c5dccf0206edeb1c1064dedfc0616df147944881a67a9cc70d911b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page