Git Product home page Git Product logo

germ's Introduction

Generate tERMinal: An application to generate terminal session recordings without rehearsing or recording

This is a command line application for generating terminal session recording files, such as asciinema's asciicast files, from a payload of inputs and outputs instead of recording a terminal session. The name comes from the progression of "generate terminal" to "genterm" to "gterm" to "germ". This is heavily inspired by the TermSheets web application, which creates animated terminal presentations from a simple JSON schema. According to the TermSheets's creator:

...Other solutions usually involve recording a live screen. I wanted a way to simply provide a payload of instructions so I didn't have to rehearse my typing and wait for network output...

While asciinema and its ecosystem is great, it is one of these "Other solutions". Similiarly, I wanted to generate terminal animations without rehearsing, and really appreciated the payload-based implementation. However, I still wanted to create the recordings from within the terminal and be able to easily share asciicasts through the asciinema.org website. The TermSheets web application required generating JSON within the website and/or copying-n-pasting from a text editor. Additional inspiration is taken from the Termynal project, which was put to excellent use by the Typer team for their documentation, but the output for Termynal is not embeddable in GitHub README files.

This is all possible because of the excellent documentation, support, and openness of all of the mentioned projects. Thank you!

Build Status

Quick Start

Start a terminal and then execute the following commands:

asciicast

Installation

Source

~$ git clone https://github.com/volks73/germ.git
~$ cd germ
~/germ$ cargo install --path .

Usage

~$ germ "echo 'Hello World'" "Hello World"
{"version":2,"width":80,"height":24,"env":{"SHELL":"/bin/sh","TERM":"xterm-256color"}}
[0.0,"o","$ "]
[0.75,"o","e"]
[0.785,"o","c"]
[0.82,"o","h"]
[0.855,"o","o"]
[0.89,"o"," "]
[0.925,"o","'"]
[0.96,"o","H"]
[0.995,"o","e"]
[1.03,"o","l"]
[1.065,"o","l"]
[1.1,"o","o"]
[1.135,"o"," "]
[1.17,"o","W"]
[1.205,"o","o"]
[1.24,"o","r"]
[1.275,"o","l"]
[1.31,"o","d"]
[1.345,"o","'"]
[2.23,"o","\r\n"]
[2.23,"o","Hello World\r\n"]
~$ germ -G "echo 'Hello World'" "Hello World" | germ -G "echo 'Hello World Again'" "Hello World Again" | germ
{"version":2,"width":80,"height":24,"env":{"SHELL":"/bin/sh","TERM":"xterm-256color"}}
[0.0,"o","$ "]
[0.75,"o","e"]
[0.785,"o","c"]
[0.82,"o","h"]
[0.855,"o","o"]
[0.89,"o"," "]
[0.925,"o","'"]
[0.96,"o","H"]
[0.995,"o","e"]
[1.03,"o","l"]
[1.065,"o","l"]
[1.1,"o","o"]
[1.135,"o"," "]
[1.17,"o","W"]
[1.205,"o","o"]
[1.24,"o","r"]
[1.275,"o","l"]
[1.31,"o","d"]
[1.345,"o","'"]
[2.23,"o","\r\n"]
[2.23,"o","Hello World\r\n"]
[2.23,"o","$ "]
[2.98,"o","e"]
[3.015,"o","c"]
[3.05,"o","h"]
[3.085,"o","o"]
[3.12,"o"," "]
[3.1550000000000002,"o","'"]
[3.19,"o","H"]
[3.225,"o","e"]
[3.26,"o","l"]
[3.295,"o","l"]
[3.33,"o","o"]
[3.365,"o"," "]
[3.4,"o","W"]
[3.435,"o","o"]
[3.4699999999999998,"o","r"]
[3.505,"o","l"]
[3.54,"o","d"]
[3.575,"o"," "]
[3.61,"o","A"]
[3.645,"o","g"]
[3.6799999999999997,"o","a"]
[3.715,"o","i"]
[3.75,"o","n"]
[3.785,"o","'"]
[4.67,"o","\r\n"]
[4.67,"o","Hello World Again\r\n"]
~$ germ -G "echo 'Hello World'" "Hello World"
{
    "version": 1,
    "commands": [
        {
            "input": "echo 'Hello World'",
            "outputs": ["Hello World"],
        },
    ]
}
~$ germ -G "echo 'Hello World'" "Hello World" > commands.json
~$ germ < commands.json
{"version":2,"width":80,"height":24,"env":{"SHELL":"/bin/sh","TERM":"xterm-256color"}}
[0.0,"o","$ "]
[0.75,"o","e"]
[0.785,"o","c"]
[0.82,"o","h"]
[0.855,"o","o"]
[0.89,"o"," "]
[0.925,"o","'"]
[0.96,"o","H"]
[0.995,"o","e"]
[1.03,"o","l"]
[1.065,"o","l"]
[1.1,"o","o"]
[1.135,"o"," "]
[1.17,"o","W"]
[1.205,"o","o"]
[1.24,"o","r"]
[1.275,"o","l"]
[1.31,"o","d"]
[1.345,"o","'"]
[2.23,"o","\r\n"]
[2.23,"o","Hello World\r\n"]
~$ cat commands.json | germ
{"version":2,"width":80,"height":24,"env":{"SHELL":"/bin/sh","TERM":"xterm-256color"}}
[0.0,"o","$ "]
[0.75,"o","e"]
[0.785,"o","c"]
[0.82,"o","h"]
[0.855,"o","o"]
[0.89,"o"," "]
[0.925,"o","'"]
[0.96,"o","H"]
[0.995,"o","e"]
[1.03,"o","l"]
[1.065,"o","l"]
[1.1,"o","o"]
[1.135,"o"," "]
[1.17,"o","W"]
[1.205,"o","o"]
[1.24,"o","r"]
[1.275,"o","l"]
[1.31,"o","d"]
[1.345,"o","'"]
[2.23,"o","\r\n"]
[2.23,"o","Hello World\r\n"]
~$ germ -i commands.json
{"version":2,"width":80,"height":24,"env":{"SHELL":"/bin/sh","TERM":"xterm-256color"}}
[0.0,"o","$ "]
[0.75,"o","e"]
[0.785,"o","c"]
[0.82,"o","h"]
[0.855,"o","o"]
[0.89,"o"," "]
[0.925,"o","'"]
[0.96,"o","H"]
[0.995,"o","e"]
[1.03,"o","l"]
[1.065,"o","l"]
[1.1,"o","o"]
[1.135,"o"," "]
[1.17,"o","W"]
[1.205,"o","o"]
[1.24,"o","r"]
[1.275,"o","l"]
[1.31,"o","d"]
[1.345,"o","'"]
[2.23,"o","\r\n"]
[2.23,"o","Hello World\r\n"]
germ -p "`printf '\u001b[32m$\u001b[39m '`" "echo 'Hello World'" "Hello World"
{"version":2,"width":80,"height":24,"env":{"SHELL":"/bin/sh","TERM":"xterm-256color"}}
[0.0,"o","\u001b[32m$ \u001b[39m"]
[0.75,"o","e"]
[0.785,"o","c"]
[0.82,"o","h"]
[0.855,"o","o"]
[0.89,"o"," "]
[0.925,"o","'"]
[0.96,"o","H"]
[0.995,"o","e"]
[1.03,"o","l"]
[1.065,"o","l"]
[1.1,"o","o"]
[1.135,"o"," "]
[1.17,"o","W"]
[1.205,"o","o"]
[1.24,"o","r"]
[1.275,"o","l"]
[1.31,"o","d"]
[1.345,"o","'"]
[2.23,"o","\r\n"]
[2.23,"o","Hello World\r\n"]
[4.23,"o",""]
~$ germ
Copyright (C) 2021  Christopher R. Field
This program comes with ABSOLUTELY NO WARRANTY; for details use the `--warranty`
flag. This is free software, and you are welcome to redistirbute it under
certain conditions; use the `--license` flag for details.

You have entered interactive mode. The prompt has similar arguments, options,
flags, and functionality to the command line interface. Use the --help flag to
print the help text.

Type CTRL+D (^D) to exit and generate output or CTRL+C (^C) to abort.

>>> "echo Hello World"
World Hello
>>> "echo Hello World Again"
Hello World Again
>>> --print
{"version":2,"width":80,"height":24,"env":{"SHELL":"/bin/sh","TERM":"xterm-256color"}}
[0.0,"o","$ "]
[0.75,"o","e"]
[0.785,"o","c"]
[0.82,"o","h"]
[0.855,"o","o"]
[0.89,"o"," "]
[0.925,"o","\""]
[0.96,"o","H"]
[0.995,"o","e"]
[1.03,"o","l"]
[1.065,"o","l"]
[1.1,"o","o"]
[1.135,"o"," "]
[1.17,"o","W"]
[1.205,"o","o"]
[1.24,"o","r"]
[1.275,"o","l"]
[1.31,"o","d"]
[1.345,"o","\""]
[2.23,"o","\r\n"]
[2.23,"o","Hello World\r\n"]
[2.23,"o","$ "]
[2.98,"o","e"]
[3.015,"o","c"]
[3.05,"o","h"]
[3.085,"o","o"]
[3.12,"o"," "]
[3.155,"o","\""]
[3.19,"o","H"]
[3.225,"o","e"]
[3.26,"o","l"]
[3.295,"o","l"]
[3.33,"o","o"]
[3.365,"o"," "]
[3.4,"o","W"]
[3.435,"o","o"]
[3.469,"o","r"]
[3.505,"o","l"]
[3.54,"o","d"]
[3.575,"o","\""]
[3.61,"o","\n"]
[3.645,"o","e"]
[3.679,"o","c"]
[3.715,"o","h"]
[3.75,"o","o"]
[3.785,"o"," "]
[3.82,"o","\""]
[3.855,"o","H"]
[3.889,"o","e"]
[3.925,"o","l"]
[3.96,"o","l"]
[3.995,"o","o"]
[4.03,"o"," "]
[4.064,"o","W"]
[4.1,"o","o"]
[4.135,"o","r"]
[4.17,"o","l"]
[4.205,"o","d"]
[4.24,"o"," "]
[4.275,"o","A"]
[4.31,"o","g"]
[4.345,"o","a"]
[4.38,"o","i"]
[4.415,"o","n"]
[4.45,"o","\""]
[5.335,"o","\r\n"]
[5.335,"o","Hello World Again\r\n"]
[7.335,"o",""]

License

The germ project is licensed under either the GPL-3.0. See the LICENSE file for more information about licensing and copyright.

germ's People

Contributors

volks73 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

germ's Issues

Add output format version option

To be paired with #3 and similar to #2, an --output-version <version> option should be added. If new revisions of the various output formats are made available, this would be used to select the appropriate encoder. The default would be the latest one available. For example, there are two versions of the asciicast format.

Add prompt to interactive mode

A prompt should be added, but I am not sure if it should be the same as the -p prompt or a different one, like python's (>>>). Maybe a -P for --interactive-prompt <prompt> would work as an option. The interactive prompt would NOT be used as the prompt in the output.

Refactor project organization for structs to modules

Everything is currently in a single file (main.rs). This is actually fine, but in order to add support for different versions and input/output formats, it would be better to separate the file format structs from the CLI structs. The single file is getting a little long as well.

Add -d,--delete flag to CLI and interactive mode

The -d,--delete flag would ignore the input and outputs arguments and remove the command that was most recently added/appended to the germ or termsheet input file or sequence state in the interactive mode.

Add commenting of inputs as lines of output

Adding comment lines before the prompt and input of a command could be useful for creating recordings for documentation. These would eventually be a different color. See the Typer documentation with their comment lines using an emoji at the beginning of the line.

Add flag to print the warranty and redistribution conditions

According to the GPL:

If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type show w'. This is free software, and you are welcome to redistribute it under certain conditions; type show c' for details.

The hypothetical commands show w' and show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

A -W,--warranty flag seems appropriate for this use and should show:

THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

A -L,--license flag seems appropriate for this use and should show:

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Add output format option

Similar to #1, but for output, an -O,--output-format <format> should be added. The default would be the asciicast format, but options for the Germ JSON, TermSheet JSON, and possibly the Termynal HTML should be supported. The -c flag would be a shortcut, or alias, for the -O germ option, but it would be nice to generate JSON capable with the TermSheet web application that could be directly copied-n-pasted.

Change interactive mode to work more like the CLI

The user may want to specify the exact output instead of having the output from the command be used. The prompt should work similar to the CLI where the first string is the input/command and if a second or more string is present, this is used as the outputs. If a second string (double quotes) is not present, the first string is executed as a shell command.

Add shell option to CLI

The shell field for the asciicast is automatically populated by the SHELL environment variable. There should be a way to override this for the recording in case a different shell is to be used for recordings.

Add input format version option

To pair with #1, an --input-version <version> should be added. The Germ JSON schema has a version field to manage changes to the schema, similar to the asciicast format and many other JSON schemas. This would indicate which format parser should be used for the input format. The default would be the latest defined version.

Truncate float values to three decimal places

Sometimes the float values for timings are extremely long when converted to a string because of floating point math. All timings should be padded/truncated to 3 decimal places for timings. This makes it easier to debug and read cast files.

Add `--now` flag to use the current unix timestamp

The --now flag should be added to indicate the current UNIX timestamp should be used for the timestamp field in the ASCIICAST header. This might need to be changed to the default behavior and the flag becomes --no-timestamp or something. The timestamp field is optional for the asciicast v2 format, but it is included when using asciinema to record a session.

Add commenting to interactive mode

A prefix, such as "#", would be used to indicate the line is a comment to be added to the command and not actually executed. The prefix would also be a CLI option to choose the character token before starting the interactive mode.

Add --print to interactive mode

The --print flag would print the current sequence state in the -O, --output-format format. This way the user can see the current progress and adjust as needed.

Add tests

Unit and integration tests should be added.

Add module-level doc comments for binary

Module-level doc comments should be added to the binary module (main.rs). This will act as the help documentation and will eventually be hosted on this project's GitHub pages. The comments should include more advanced usage examples and details.

Print header/introduction matter to stdout when entering interactive mode

When entering interactive mode, some initial introduction information indicating how to use the application in interactive mode, copyright, etc. should be printed to stdout. This way, it interactive mode is entered by accident, it is easy to get out of it and know what to do. This will also avoid problems for users that enter the mode and think the application is hanging or stalled.

Change all usage examples to terminal session recordings

Each of the usage examples should be converted to terminal session recordings. Most likely these would be asciinema SVGs with links to the asciicast file hosted at asciinema.org. This would be a better example of the application and its utility.

Add timestamp option

Setting the timestamp and/or using the current system time is missing. It is an optional field for the asciicast header, but having the option to set it and/or include it as the current system time would be useful.

This one was kind of overlooked because originally it just defaulted to the current system time.

Add input format option

An -I,--input-format <format> option should be added to the CLI. The default is the Germ JSON schema, but the TermSheet JSON schema should be supported as well. Valid options would be Germ (default) and TermSheet. Other formats will be added as requested. I think reading and decoding asciicast files is a little beyond the scope of this project at the moment.

Add execution mode for input

A -E,--execute flag should be added. When it is used, the <input> argument would be executed as a command, similar to the stdin line of the interactive mode and the <outputs> argument would not be needed.

Add Termynal output format support

The Termynal project uses a HTML-based format for creating terminal session recordings. This should be relatively straightforward to replicate now that comments and timings are implemented. I am not sure about reading in Termynal files, but I will investigate the format.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.