• Stars
    star
    272
  • Rank 146,290 (Top 3 %)
  • Language
    Go
  • License
    MIT License
  • Created over 4 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A framework for performing live pre-recorded command line demos in the wild 📼

demo

ci codecov docs

demo

A framework for performing live pre-recorded command line demos in the wild 📼

Recording command line demos can be a difficult topic these days. Doing a video record has the drawback of lacking flexibility and reduced interactivity during the demo. Typing everything by our own is error prone and distracts the audience from the actual topic we want to show them. So we need something in between, which is easy to use…

This framework should solve the issue by provided interactive demos from your command line!

Usage

Every demo is a stand-alone command line application which consist of multiple runs. For example, if we create a demo like this:

package main

import (
	demo "github.com/saschagrunert/demo"
)

func main() {
	demo.New().Run()
}

Then this demo already contains features like auto-play. We can verify this checking the help output of the executable:

NAME:
   main - A new cli application

USAGE:
   main [global options] command [command options] [arguments...]

VERSION:
   0.0.0

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --all, -l                     run all demos (default: false)
   --auto, -a                    run the demo in automatic mode, where every step gets executed automatically (default: false)
   --auto-timeout auto, -t auto  the timeout to be waited when auto is enabled (default: 3s)
   --continuously, -c            run the demos continuously without any end (default: false)
   --immediate, -i               immediately output without the typewriter animation (default: false)
   --hide-descriptions, -d       hide descriptions between the steps (default: false)
   --skip-steps value, -s value  skip the amount of initial steps within the demo (default: 0)
   --help, -h                    show help (default: false)
   --version, -v                 print the version (default: false)

The application is based on the urfave/cli framework, which means that we have every possibility to change the app before actually running it.

// Create a new demo CLI application
d := demo.New()

// A demo is an usual urfave/cli application, which means
// that we can set its properties as expected:
d.Name = "A demo of something"
d.Usage = "Learn how this framework is being used"
d.HideVersion = true

Creating runs inside demos

To have something to show, we need to create a run and add it to the demo. This can be done by using the demo.Add() method:

func main() {
	// Create a new demo CLI application
	d := demo.New()

	// Register the demo run
	d.Add(example(), "demo-0", "just an example demo run")

	// Run the application, which registers all signal handlers and waits for
	// the app to exit
	d.Run()
}

// example is the single demo run for this application
func example() *Run {
	// A new run contains a title and an optional description
	r := NewRun(
		"Demo Title",
		"Some additional",
		"multi-line description",
		"is possible as well!",
	)

	// A single step can consist of a description and a command to be executed
	r.Step(S(
		"This is a possible",
		"description of the following command",
		"to be executed",
	), S(
		"echo hello world",
	))

	// Commands do not need to have a description, so we could set it to `nil`
	r.Step(nil, S(
		"echo without description",
		"but this can be executed in",
		"multiple lines as well",
	))

	// It is also not needed at all to provide a command
	r.Step(S(
		"Just a description without a command",
	), nil)

	return r
}

The example() function creates a new demo run, which itself contains of multiple steps. These steps are executed in order, can contain a description and a command to be executed. Wrapping commands in multiple lines will automatically create a line break in the command line.

Setup and Cleanup functions

It is also possible to do something before or after each run. For this the setup and cleanup functions can be set to the demo:

func main() {
	// Create a new demo CLI application
	d := demo.New()

	// Be able to run a Setup/Cleanup function before/after each run
	d.Setup(setup)
	d.Cleanup(cleanup)
}

// setup will run before every demo
func setup(ctx *cli.Context) error {
	// Ensure can be used for easy sequential command execution
	return Ensure(
		"echo 'Doing first setup…'",
		"echo 'Doing second setup…'",
		"echo 'Doing third setup…'",
	)
}

// setup will run after every demo
func cleanup(ctx *cli.Context) error {
	return Ensure("echo 'Doing cleanup…'")
}

Contributing

You want to contribute to this project? Wow, thanks! So please just fork it and send me a pull request.

More Repositories

1

webapp.rs

A web application completely written in Rust. 🌍
Rust
2,160
star
2

kubernix

Single dependency Kubernetes clusters for local testing, experimenting and development
Rust
710
star
3

demystifying-containers

A series of blog posts and talks about the world of containers 📦
Python
676
star
4

git-journal

The Git Commit Message and Changelog Generation Framework 📖
Rust
564
star
5

indextree

Arena based tree 🌲 structure by using indices instead of reference counted pointers
Rust
533
star
6

nn

A tiny neural network 🧠
Haskell
121
star
7

rain

Visualize vertical data inside your terminal 💦
Rust
88
star
8

ccli

Command line parsing in go, with coloring support 🌈
Go
83
star
9

func

Functional additions to C
C++
55
star
10

dotfiles

My hand crafted .dotfiles 🤚🛠❤️
Shell
48
star
11

performabot

Continuous performance analysis reports for software projects 🤖
Haskell
41
star
12

kmod

A Linux kernel module written in Rust
Rust
34
star
13

craft

Cargo inspired build system for C based projects
Rust
32
star
14

kubeflow-data-science-on-steroids

The blog post about Kubeflow, including all materials
Jupyter Notebook
30
star
15

go-modiff

Command line tool for diffing go module dependency changes between versions 📔
Go
29
star
16

yew-router

Router extension to yew
Rust
27
star
17

peel-ip

Packet parsing for the Internet Protocol Suite 📦
Rust
26
star
18

microservice-rs

Microservice template using Rust and Cap'n Proto RPCs.
Rust
26
star
19

peel

Dynamic packet parsing within trees 🌲🌳🌴
Rust
22
star
20

fosdem20

Demo material used for the Podman talk at FOSDEM 2020
Go
22
star
21

stm32h7-rs

Rust on STM32H7 Microcontrollers
Rust
14
star
22

syscall-recorder

ebpf syscall recording demo project
C
9
star
23

unibar

A GPU accelerated status bar written in Rust 🦄
Rust
8
star
24

seer

A collaborative resource planning tool 🔮
Haskell
5
star
25

fastcmp

A fast byte slice comparison library
Rust
5
star
26

path

IP based connection identification and tracing 👟
Rust
5
star
27

webapp.hs

Haskell
4
star
28

umask-observe

umask observability based on bpftrace for OpenShift nodes
Shell
3
star
29

mowl

My own little logger ✏️
Rust
3
star
30

crio-demos

CRI-O Demonstration Material
Go
3
star
31

rapidc

Rust
2
star
32

failure

Pure and type driven error handling for Haskell
Haskell
2
star
33

build-rust

The Docker based Rust build toolchain
Dockerfile
2
star
34

pidwatch-rs

C
2
star
35

kubeflow-notebook-gpu

Kubeflow GPU Notebook Container Image
Dockerfile
2
star
36

pinns.rs

A simple utility to pin Linux namespaces
Rust
2
star
37

backingFsBlockDev

Go
1
star
38

peeler

Peel your network traffic
Rust
1
star
39

tunneldevice

Playing around with tunnel devices in Rust
Rust
1
star
40

build-haskell

The Docker based Haskell build toolchain
Dockerfile
1
star
41

go-docgen

A markdown and man page documentation generator for go applications
Go
1
star
42

netfilter_kmod

Playing around with the netfilter within the kernel
C
1
star
43

ci

Haskell
1
star
44

netlink_kmod

Playing around with routing netlinks inside the kernel
C
1
star
45

seccomp-oci-artifact-demo

Go
1
star