Skip to content

Commit 526dbec

Browse files
committed
Add asciicast
1 parent 7637a15 commit 526dbec

4 files changed

Lines changed: 285 additions & 0 deletions

File tree

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
{"version": 2, "width": 173, "height": 36, "timestamp": 1774700938, "env": {"SHELL": "/usr/bin/zsh", "TERM": "xterm-256color"}}
2+
[0.006587, "o", "/home/ben/Programming/dfetch/doc/generate-casts/interactive-add /home/ben/Programming/dfetch/doc/generate-casts\r\n"]
3+
[0.008298, "o", "\u001b[H\u001b[2J\u001b[3J"]
4+
[0.010979, "o", "$ "]
5+
[1.015209, "o", "\u001b["]
6+
[1.195997, "o", "1m"]
7+
[1.286008, "o", "ca"]
8+
[1.37609, "o", "t "]
9+
[1.46629, "o", "df"]
10+
[1.55649, "o", "et"]
11+
[1.646659, "o", "ch"]
12+
[1.73682, "o", ".y"]
13+
[1.826954, "o", "am"]
14+
[1.917222, "o", "l\u001b"]
15+
[2.097806, "o", "[0"]
16+
[2.188207, "o", "m"]
17+
[3.190293, "o", "\r\n"]
18+
[3.194309, "o", "manifest:\r\n version: '0.0'\r\n projects:\r\n - name: jsmn\r\n url: https://github.com/zserge/jsmn.git\r\n branch: master\r\n"]
19+
[3.200461, "o", "$ "]
20+
[4.204728, "o", "\u001b"]
21+
[4.384922, "o", "[1"]
22+
[4.475222, "o", "md"]
23+
[4.565241, "o", "fe"]
24+
[4.655321, "o", "t"]
25+
[4.745924, "o", "ch"]
26+
[4.835907, "o", " a"]
27+
[4.926012, "o", "dd"]
28+
[5.016554, "o", " -"]
29+
[5.106995, "o", "i"]
30+
[5.287819, "o", " h"]
31+
[5.378229, "o", "tt"]
32+
[5.46872, "o", "ps"]
33+
[5.559124, "o", ":/"]
34+
[5.649617, "o", "/"]
35+
[5.740014, "o", "gi"]
36+
[5.830347, "o", "th"]
37+
[5.920526, "o", "ub"]
38+
[6.010971, "o", ".c"]
39+
[6.191347, "o", "o"]
40+
[6.281511, "o", "m/"]
41+
[6.371949, "o", "cp"]
42+
[6.462498, "o", "pu"]
43+
[6.552779, "o", "te"]
44+
[6.643174, "o", "s"]
45+
[6.73357, "o", "t/"]
46+
[6.823951, "o", "cp"]
47+
[6.914134, "o", "pu"]
48+
[7.094652, "o", "te"]
49+
[7.185069, "o", "s"]
50+
[7.275514, "o", "t."]
51+
[7.365747, "o", "gi"]
52+
[7.45584, "o", "t\u001b"]
53+
[7.546246, "o", "[0"]
54+
[7.636649, "o", "m"]
55+
[8.639035, "o", "\r\n"]
56+
[8.826, "o", "\u001b[1;34mDfetch (0.12.1)\u001b[0m\r\n"]
57+
[9.348012, "o", " \u001b[1;92mhttps://github.com/cpputest/cpputest.git:\u001b[0m\r\n"]
58+
[9.349009, "o", " \u001b[1;34m> Adding project through interactive wizard\u001b[0m\r\n \u001b[92m?\u001b[0m Name: \u001b[2mcpputest\u001b[0m"]
59+
[23.37253, "o", "\r\n\u001b[1A\u001b[2K"]
60+
[23.374059, "o", " - \u001b[34mname:\u001b[0m cpputest\r\n"]
61+
[23.374889, "o", " \u001b[34murl:\u001b[0m https://github.com/cpputest/cpputest.git\r\n \u001b[92m?\u001b[0m Destination: \u001b[2mcpputest\u001b[0m"]
62+
[25.161399, "o", "\r\n\u001b[1A\u001b[2K"]
63+
[25.973393, "o", " \u001b[92m?\u001b[0m \u001b[1mVersion:\u001b[0m\r\n \u001b[92m▶\u001b[0m \u001b[1mmaster \u001b[2mbranch\u001b[0m \u001b[2m(default)\u001b[0m\u001b[0m\r\n 3.7.2 \u001b[2mtag\u001b[0m\r\n gh-pages \u001b[2mbranch\u001b[0m\r\n latest-passing-build \u001b[2mtag\u001b[0m\r\n ▸ revert-1598-fix\r\n separate_gtest \u001b[2mbranch\u001b[0m\r\n v3.3 \u001b[2mtag\u001b[0m\r\n v3.4 \u001b[2mtag\u001b[0m\r\n v3.5 \u001b[2mtag\u001b[0m\r\n v3.6 \u001b[2mtag\u001b[0m\r\n \u001b[2m↓ 4 more below\u001b[0m\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc list\u001b[0m\r\n"]
64+
[28.321672, "o", "\u001b[13A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mVersion:\u001b[0m\r\n master \u001b[2mbranch\u001b[0m \u001b[2m(default)\u001b[0m\r\n \u001b[92m▶\u001b[0m \u001b[1m3.7.2 \u001b[2mtag\u001b[0m\u001b[0m\r\n gh-pages \u001b[2mbranch\u001b[0m\r\n latest-passing-build \u001b[2mtag\u001b[0m\r\n ▸ revert-1598-fix\r\n separate_gtest \u001b[2mbranch\u001b[0m\r\n v3.3 \u001b[2mtag\u001b[0m\r\n v3.4 \u001b[2mtag\u001b[0m\r\n v3.5 \u001b[2mtag\u001b[0m\r\n v3.6 \u001b[2mtag\u001b[0m\r\n \u001b[2m↓ 4 more below\u001b[0m\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc list\u001b[0m\r\n"]
65+
[28.712652, "o", "\u001b[13A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mVersion:\u001b[0m\r\n master \u001b[2mbranch\u001b[0m \u001b[2m(default)\u001b[0m\r\n 3.7.2 \u001b[2mtag\u001b[0m\r\n \u001b[92m▶\u001b[0m \u001b[1mgh-pages \u001b[2mbranch\u001b[0m\u001b[0m\r\n latest-passing-build \u001b[2mtag\u001b[0m\r\n ▸ revert-1598-fix\r\n separate_gtest \u001b[2mbranch\u001b[0m\r\n v3.3 \u001b[2mtag\u001b[0m\r\n v3.4 \u001b[2mtag\u001b[0m\r\n v3.5 \u001b[2mtag\u001b[0m\r\n v3.6 \u001b[2mtag\u001b[0m\r\n \u001b[2m↓ 4 more below\u001b[0m\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc list\u001b[0m\r\n"]
66+
[29.637058, "o", "\u001b[13A\u001b[0J"]
67+
[29.638165, "o", " \u001b[34mbranch:\u001b[0m gh-pages\r\n"]
68+
[30.335169, "o", " \u001b[92m?\u001b[0m \u001b[1mSource path:\u001b[0m\r\n \u001b[92m▶\u001b[0m ▸ \u001b[1mimages\u001b[0m\r\n ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc skip\u001b[0m\r\n"]
69+
[32.17768, "o", "\u001b[7A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mSource path:\u001b[0m\r\n \u001b[92m▶\u001b[0m ▾ \u001b[1mimages\u001b[0m\r\n bkg.png\r\n blacktocat.png\r\n ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc skip\u001b[0m\r\n"]
70+
[32.884474, "o", "\u001b[9A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mSource path:\u001b[0m\r\n ▾ images\r\n \u001b[92m▶\u001b[0m \u001b[1mbkg.png\u001b[0m\r\n blacktocat.png\r\n ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc skip\u001b[0m\r\n"]
71+
[33.455716, "o", "\u001b[9A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mSource path:\u001b[0m\r\n ▾ images\r\n bkg.png\r\n \u001b[92m▶\u001b[0m \u001b[1mblacktocat.png\u001b[0m\r\n ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc skip\u001b[0m\r\n"]
72+
[34.978763, "o", "\u001b[9A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mSource path:\u001b[0m\r\n ▾ images\r\n \u001b[92m▶\u001b[0m \u001b[1mbkg.png\u001b[0m\r\n blacktocat.png\r\n ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc skip\u001b[0m\r\n"]
73+
[35.218496, "o", "\u001b[9A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mSource path:\u001b[0m\r\n \u001b[92m▶\u001b[0m ▾ \u001b[1mimages\u001b[0m\r\n bkg.png\r\n blacktocat.png\r\n ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc skip\u001b[0m\r\n"]
74+
[35.479506, "o", "\u001b[9A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mSource path:\u001b[0m\r\n \u001b[92m▶\u001b[0m ▾ \u001b[1mimages\u001b[0m\r\n bkg.png\r\n blacktocat.png\r\n ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc skip\u001b[0m\r\n"]
75+
[35.898403, "o", "\u001b[9A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mSource path:\u001b[0m\r\n \u001b[92m▶\u001b[0m ▸ \u001b[1mimages\u001b[0m\r\n ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Enter select →/← expand/collapse Esc skip\u001b[0m\r\n"]
76+
[37.730104, "o", "\u001b[7A\u001b[0J"]
77+
[37.733523, "o", " \u001b[92m?\u001b[0m \u001b[1mIgnore:\u001b[0m\r\n \u001b[92m▶\u001b[0m ▸ images\r\n ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Space toggle Enter confirm →/← expand/collapse Esc skip\u001b[0m\r\n"]
78+
[40.116121, "o", "\u001b[7A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mIgnore:\u001b[0m\r\n \u001b[92m▶\u001b[0m ▸ \u001b[2mimages\u001b[0m\r\n ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Space toggle Enter confirm →/← expand/collapse Esc skip\u001b[0m\r\n"]
79+
[40.298184, "o", "\u001b[7A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mIgnore:\u001b[0m\r\n ▸ \u001b[2mimages\u001b[0m\r\n \u001b[92m▶\u001b[0m ▸ javascripts\r\n ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Space toggle Enter confirm →/← expand/collapse Esc skip\u001b[0m\r\n"]
80+
[40.460012, "o", "\u001b[7A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mIgnore:\u001b[0m\r\n ▸ \u001b[2mimages\u001b[0m\r\n ▸ javascripts\r\n \u001b[92m▶\u001b[0m ▸ stylesheets\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Space toggle Enter confirm →/← expand/collapse Esc skip\u001b[0m\r\n"]
81+
[40.790247, "o", "\u001b[7A\u001b[0J \u001b[92m?\u001b[0m \u001b[1mIgnore:\u001b[0m\r\n ▸ \u001b[2mimages\u001b[0m\r\n ▸ javascripts\r\n \u001b[92m▶\u001b[0m ▸ \u001b[2mstylesheets\u001b[0m\r\n index.html\r\n params.json\r\n \u001b[2m↑/↓ navigate Space toggle Enter confirm →/← expand/collapse Esc skip\u001b[0m\r\n"]
82+
[41.777204, "o", "\u001b[7A\u001b[0J"]
83+
[41.778195, "o", " \u001b[34mignore:\u001b[0m\r\n"]
84+
[41.77866, "o", " - images\r\n"]
85+
[41.779063, "o", " - stylesheets\r\n"]
86+
[41.781633, "o", "Add project to manifest? \u001b[1m(\u001b[0my\u001b[1m)\u001b[0m: "]
87+
[42.332364, "o", "y"]
88+
[42.392338, "o", "\r\n"]
89+
[42.394097, "o", " \u001b[1;92mcpputest:\u001b[0m\r\n"]
90+
[42.39471, "o", " \u001b[1;34m> Added 'cpputest' to manifest '/home/ben/Programming/dfetch/doc/generate-casts/interactive-add/dfetch.yaml'\u001b[0m\r\n"]
91+
[42.395114, "o", "Run \u001b[32m'dfetch update cpputest'\u001b[0m now? \u001b[1m(\u001b[0my\u001b[1m)\u001b[0m: "]
92+
[42.945802, "o", "n"]
93+
[43.005827, "o", "\r\n"]
94+
[43.063622, "o", "$ "]
95+
[44.068765, "o", "\u001b["]
96+
[44.249547, "o", "1m"]
97+
[44.339916, "o", "ca"]
98+
[44.429885, "o", "t "]
99+
[44.520499, "o", "df"]
100+
[44.610923, "o", "et"]
101+
[44.701311, "o", "ch"]
102+
[44.791622, "o", ".y"]
103+
[44.882051, "o", "am"]
104+
[44.972463, "o", "l\u001b"]
105+
[45.153102, "o", "[0m"]
106+
[46.155253, "o", "\r\n"]
107+
[46.159809, "o", "manifest:\r\n version: '0.0'\r\n projects:\r\n - name: jsmn\r\n url: https://github.com/zserge/jsmn.git\r\n branch: master\r\n\r\n - name: cpputest\r\n url: https://github.com/cpputest/cpputest.git\r\n branch: gh-pages\r\n ignore:\r\n - images\r\n - stylesheets\r\n"]
108+
[49.169724, "o", "$ "]
109+
[49.171498, "o", "\u001b"]
110+
[49.351954, "o", "[1"]
111+
[49.441951, "o", "m\u001b"]
112+
[49.532505, "o", "[0"]
113+
[49.622908, "o", "m"]
114+
[49.623649, "o", "\r\n"]
115+
[49.627644, "o", "/home/ben/Programming/dfetch/doc/generate-casts\r\n"]

doc/generate-casts/generate-casts.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export TZ=UTC
1111

1212
rm -rf ../asciicasts/*
1313

14+
asciinema rec --overwrite -c "./interactive-add-demo.sh" ../asciicasts/interactive-add.cast
1415
asciinema rec --overwrite -c "./basic-demo.sh" ../asciicasts/basic.cast
1516
asciinema rec --overwrite -c "./init-demo.sh" ../asciicasts/init.cast
1617
asciinema rec --overwrite -c "./add-demo.sh" ../asciicasts/add.cast
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env bash
2+
# Demo of dfetch add -i (interactive wizard mode).
3+
#
4+
# Uses the real cpputest repository so the viewer sees dfetch fetching live
5+
# branch/tag metadata and the wizard populating from it.
6+
7+
source ./demo-magic/demo-magic.sh
8+
9+
PROMPT_TIMEOUT=1
10+
11+
mkdir interactive-add
12+
pushd interactive-add
13+
14+
# Start with a manifest that already has one dependency so the demo shows
15+
# adding to an existing project rather than starting from scratch.
16+
cat > dfetch.yaml << 'MANIFEST'
17+
manifest:
18+
version: '0.0'
19+
projects:
20+
- name: jsmn
21+
url: https://github.com/zserge/jsmn.git
22+
branch: master
23+
MANIFEST
24+
25+
clear
26+
27+
pe "cat dfetch.yaml"
28+
29+
p "dfetch add -i https://github.com/cpputest/cpputest.git"
30+
python3 ../interactive_add_helper.py https://github.com/cpputest/cpputest.git
31+
32+
pe "cat dfetch.yaml"
33+
34+
PROMPT_TIMEOUT=3
35+
wait
36+
37+
pei ""
38+
39+
popd
40+
rm -rf interactive-add
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/usr/bin/env python3
2+
"""Drive ``dfetch add -i`` with simulated typing for asciinema recordings.
3+
4+
Usage::
5+
6+
python3 interactive-add-helper.py <remote-url>
7+
8+
Every Rich ``Prompt.ask`` / ``Confirm.ask`` call is intercepted:
9+
10+
1. The prompt markup is rendered to the terminal exactly as dfetch would.
11+
2. After a short "thinking" pause each answer character is written to stdout
12+
one at a time, mimicking natural typing speed.
13+
3. The answer is returned to dfetch as if the user had pressed Enter.
14+
15+
``is_tty`` is forced to ``False`` so that dfetch uses the text-based
16+
fallbacks (numbered version list, plain src/ignore prompts) rather than
17+
the raw-terminal tree browser – the text fallback looks better on a cast.
18+
19+
Answers
20+
-------
21+
``None`` in a prompt-answer slot means "accept the default" – the default
22+
value is typed out so the viewer can read what was chosen. An explicit
23+
string overrides the default.
24+
"""
25+
26+
from __future__ import annotations
27+
28+
import sys
29+
import time
30+
from collections import deque
31+
from unittest.mock import patch
32+
33+
from rich.console import Console
34+
35+
# ---------------------------------------------------------------------------
36+
# Wizard answers – customise these to change what the demo shows
37+
# ---------------------------------------------------------------------------
38+
_PROMPT_ANSWERS: deque[str | None] = deque(
39+
[
40+
None, # Name – accept the default (derived from URL)
41+
"ext/cpputest", # Destination – show the common ext/ convention
42+
None, # Version – accept the default branch
43+
None, # Source path – press Enter to fetch the whole repo
44+
None, # Ignore paths – press Enter to skip
45+
]
46+
)
47+
_CONFIRM_ANSWERS: deque[bool] = deque(
48+
[
49+
True, # "Add project to manifest?" → yes
50+
False, # "Run 'dfetch update' now?" → no
51+
]
52+
)
53+
54+
# ---------------------------------------------------------------------------
55+
# Timing (seconds) – tweak for faster/slower recording
56+
# ---------------------------------------------------------------------------
57+
_PRE_DELAY = 0.55 # pause before starting to type (user "thinking")
58+
_CHAR_DELAY = 0.06 # delay between consecutive characters
59+
60+
# ---------------------------------------------------------------------------
61+
# Internal helpers
62+
# ---------------------------------------------------------------------------
63+
_console = Console(force_terminal=True)
64+
65+
66+
def _type_out(text: str) -> None:
67+
"""Write *text* to stdout one character at a time, then a newline."""
68+
time.sleep(_PRE_DELAY)
69+
for ch in text:
70+
sys.stdout.write(ch)
71+
sys.stdout.flush()
72+
time.sleep(_CHAR_DELAY)
73+
sys.stdout.write("\n")
74+
sys.stdout.flush()
75+
76+
77+
# ---------------------------------------------------------------------------
78+
# Prompt replacements
79+
# ---------------------------------------------------------------------------
80+
81+
82+
def _fake_prompt_ask(prompt_markup: str, *, default: str = "", **_kw: object) -> str:
83+
"""Render the Rich-markup prompt, then simulate typing the next answer.
84+
85+
``None`` in the queue means "accept the default" – the default is
86+
typed out (visible to the viewer) rather than silently accepted.
87+
"""
88+
suffix = f" [{default}]" if default else ""
89+
_console.print(f"{prompt_markup}{suffix}: ", end="")
90+
91+
raw = _PROMPT_ANSWERS.popleft() if _PROMPT_ANSWERS else None
92+
answer = raw if raw is not None else default
93+
_type_out(answer)
94+
return answer
95+
96+
97+
def _fake_confirm_ask(
98+
prompt_markup: str, *, default: bool = True, **_kw: object
99+
) -> bool:
100+
"""Render the confirm prompt, then simulate typing y or n."""
101+
yn_hint = "y" if default else "n"
102+
_console.print(f"{prompt_markup} [y/n] ({yn_hint}): ", end="")
103+
104+
val = _CONFIRM_ANSWERS.popleft() if _CONFIRM_ANSWERS else default
105+
_type_out("y" if val else "n")
106+
return val
107+
108+
109+
# ---------------------------------------------------------------------------
110+
# Entry point
111+
# ---------------------------------------------------------------------------
112+
113+
if __name__ == "__main__":
114+
if len(sys.argv) < 2:
115+
sys.exit("Usage: interactive-add-helper.py <remote-url>")
116+
117+
url = sys.argv[1]
118+
119+
# Force text-mode prompts so dfetch uses the numbered list + plain prompts
120+
# instead of the raw-TTY tree browser.
121+
import dfetch.terminal.keys as _keys
122+
123+
_keys.is_tty = lambda: False # type: ignore[assignment]
124+
125+
with patch("rich.prompt.Prompt.ask", side_effect=_fake_prompt_ask):
126+
with patch("rich.prompt.Confirm.ask", side_effect=_fake_confirm_ask):
127+
from dfetch.__main__ import run
128+
129+
run(["add", "--interactive", url], _console)

0 commit comments

Comments
 (0)