Skip to content

Record πŸ’­ comments and ❯ commands from from shell scripts in addition to their output.

License

Notifications You must be signed in to change notification settings

zechris/asciinema-rec_script

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

16 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

asciinema-rec_script

Conventional Commits

Record πŸ’­ comments and ❯ commands from from shell scripts in addition to their output.

This is done by building a version of the original script that surfaces all the comments and commands by also echoing them to the screen.

Then passing that augmented script to asciinema's rec --command command.

Motivation

The asciinema tool is an awesome terminal session recorder.

And it has a rec [filename] command with a -c --command=<command> option.

This specifies a command to record (other than the default of $SHELL)

So given an (executable) script screencasts/demo-date_maths:

#!/usr/bin/env bash
## Date maths

# The `date` command can be used to retrieve the:
#  * *day of the week* using the `%l` option
day_of_the_week=$(date +%l)

#  * *hour of the day* using the `%u` option
hour=$(date +%u)


# Now, can you guess what we're going to do with those two numbers?
# πŸ€”...
sleep 3

# We're going to add them together!
echo $((day_of_the_week + hour))

We can use asciinema's rec to make a recording:

asciinema rec --command screencasts/demo-date_maths

However that recording is going to lose a bunch of context from the script and end up looking something like this: Screen Shot 2021-10-17 at 19 49 14

If, however we instead used this command:

asciinema-rec_script screencasts/demo-date_maths

Without any effort we can end up with a recording like this: demo-date_maths.cast

Getting Started

Installation:

Place asciinema-rec_script somewhere in your $PATH.

Requirements:

Example Usages:

  • asciinema-rec_script ./screencasts/demo-date_maths
    • When called with no extra arguments, the tool will pass asciinema rec a filename of ./screencasts/demo-date_maths.cast to place the recording in
    • (Nb. the filename is derived from the source script by attaching a .cast extension.)
  • ./screencasts/demo-date_maths.asc
    • Will take advantage of the shebang line #!/usr/bin/env asciinema-rec_script in the .asc script
    • (ie. allowing the input script to be run as its own command, without having to pass it as an argument to asciinema-rec_script)
  • ./screencasts/demo-date_maths.asc --
    • When called with -- the tool will allow asciinema rec to receive no additional arguments
    • (ie. allowing it to maintain its default behaviour of uploading screencasts to https://asciinema.org)
  • ./screencasts/demo-date_maths.asc --help
    • Will also pass any additional arguments it gets to asciinema rec
    • (so eg. --help will show all the asciinema rec [options])
  • SLEEP=0 ./screencasts/demo-bash_functions.asc
    • (env vars can be passed into the script in the regular way)
    • (to eg set PROMPT="$ ", PROMPT_PAUSE=5)
  • bash ./screencasts/demo-date_maths.asc
    • Nb. It should also be possibe to execute the .asc script in your $SHELL as a regular bash script
    • (Maintaining this compatability means that the .asc file won't require any special commands that a regular shell script wouldn't already have in it. Which hopefully results in regular shell scripts resulting in half-decent looking recordings.)

(Nb. the .asc extension ("ASCiinema") is not strictly necessary, but gives some uniformity.)

How it works

asciinema-rec_script (written in bash) reads from the file passed to it one line at a time and will detect:

  • ❯ lines of code (syntax highlighting them as bash code)
  • πŸ’­ comments (syntax highlighting them as markdown)
  • blank lines (preserving whitespace)
  • πŸ’¬ and some other special lines

It uses meta-programming to build an augmented version of itself from each of these lines storing them in a temporary augmented_script file.

And finally it passes that file (and any other arguments specified on the command line) to asciinema run --command <augmented_script> for it to make a recording.

Nb. although the .asc scripts are used to produced asciinema recordings its expected that these files can also be run in bash/zsh

eg.

❯ source screencasts/demo-bash_functions.asc
a='a 0', b='b 0', c=''
-> f1(a='a 0', b='b 0', c='')
-> f1(a='a 0', b='b 0', c='')
BEFORE: a='a 0', b='b 0', c=''
-> f1(a='a 1', b='b 1', c='c 1')
AFTER : a='a 1', b='b 1', c='c 1'
BEFORE: a='a 0', b='b 0', c=''
-> f1(a='a 1', b='b 1', c='c 1')
AFTER : a='a 0', b='b 0', c=''
-> f1(a='a 1', b='b 2', c='c 2')
-> f1(a='a 1', b='b 0', c='c 2')
Sun Oct 17 20:56:56 AEDT 2021
-> f1(a='a 1', b='b 0', c='Sun Oct 17 20:56:56 AEDT 2021')
BEFORE: a='a 0', b='b 0', c=''
-> f1(a='a 1', b='b 3', c='c 3')
AFTER : a='a 0', b='b 0', c=''
-> f2(a='a 4', b='b 4', c='Sun Oct 17 20:56:56 AEDT 2021')
-> f2(a='a 4', b='b 4', c='Sun Oct 17 20:56:56 AEDT 2021')
-> f2(a='a 4', b='b 4', c='c 4')

Limitations

As the .asc is read in one line at a time, making it difficult (if not impossible) to execute multi-line commands in these shell scripts.

The two workarounds I could think of were:

  1. making every multi-line command fit on one line
  • So this:
    f1() {
      echo "-> f1(a='$a', b='$b', c='$c')"
    }
  • would have to be manually edited in the .asc file to this:
    f1() { echo "-> f1(a='$a', b='$b', c='$c')"; }
  1. inline the multi-line code from a source command:
  • So something like this:
    source "${script%.asc}/f1.1"
  • could be used (eg. here) to source this file but be seemlessly displayed in the recording as:
    f1() {
      echo "-> f1(a='$a', b='$b', c='$c')"
    }

Similar & Related Projects

Also included

This tool provides a command line playack menu of screencasts which it pulls from github repos.

It works with both public & private github repos.

(Nb. The recordings that appear in the menu don't necessarily have to be made using asciinema-rec_script, but the menu will filter out all the .asc files from that directory.)

Requirements:

Example Usages:

  • asciinema-gh zechris/asciinema-rec_script
  • REF=v0.9.0 asciinema-gh zechris/asciinema-rec_script
    • (which can be used with a github REFs like release tags eg. v0.9.0)
  • REF=first_pr asciinema-gh zechris/asciinema-rec_script
  • asciinema-gh spectreconsole/spectre.console docs/input/assets/casts
    • (NB. a path can also be specified if the screencasts aren't found in the default ./screencasts)
  • echo 26 | screencast_dir=docs/input/assets/casts asciinema-gh spectreconsole/spectre.console
    • (to pre-select number 26 from the menu)

asciicast