pytorial 0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pytorial-0.1.dist-info/METADATA +172 -0
- pytorial-0.1.dist-info/RECORD +15 -0
- pytorial-0.1.dist-info/WHEEL +4 -0
- pytorial-0.1.dist-info/entry_points.txt +4 -0
- pytorial-0.1.dist-info/licenses/LICENSE +21 -0
- tutorial/__init__.py +41 -0
- tutorial/catalog.py +527 -0
- tutorial/cli.py +1714 -0
- tutorial/model.py +81 -0
- tutorial/run.py +688 -0
- tutorial/shell.py +336 -0
- tutorial/state.py +207 -0
- tutorial/tutorials/shell-basics.md +101 -0
- tutorial/tutorials/using-tutorials.md +212 -0
- tutorial/tutorials/writing-tutorials.md +414 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pytorial
|
|
3
|
+
Version: 0.1
|
|
4
|
+
Summary: Interactive command-line tutorials with PTY-backed steps
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: Daniel Bosk
|
|
8
|
+
Author-email: daniel@bosk.se
|
|
9
|
+
Maintainer: Daniel Bosk
|
|
10
|
+
Maintainer-email: dbosk@kth.se
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
15
|
+
Classifier: Intended Audience :: Education
|
|
16
|
+
Classifier: Topic :: Education
|
|
17
|
+
Requires-Dist: PyYAML (>=6)
|
|
18
|
+
Requires-Dist: platformdirs (>=4)
|
|
19
|
+
Requires-Dist: rich (>=12.3.0)
|
|
20
|
+
Requires-Dist: typer (>=0.9.0)
|
|
21
|
+
Project-URL: Bug Tracker, https://github.com/dbosk/tutorial/issues
|
|
22
|
+
Project-URL: Repository, https://github.com/dbosk/tutorial
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# tutorial
|
|
26
|
+
|
|
27
|
+
A Python library for interactive command-line tutorials.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
pipx install tutorial
|
|
33
|
+
# or
|
|
34
|
+
uv tool install tutorial
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
To run from a clone instead of an installed copy, see
|
|
38
|
+
[`CONTRIBUTING.md`](CONTRIBUTING.md).
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
The package ships with three built-in tutorials. The first one is a
|
|
43
|
+
self-guided tour of the tool itself:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
tutorial run using-tutorials
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Companion tours: `tutorial run shell-basics` (shell and editor skills)
|
|
50
|
+
and `tutorial run writing-tutorials` (authoring tutorials of your own).
|
|
51
|
+
|
|
52
|
+
### Discover what's available
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
tutorial list
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Pipe the same command into a script to get tab-separated rows instead
|
|
59
|
+
of the rich table.
|
|
60
|
+
|
|
61
|
+
### Run or resume
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
tutorial run <id> # start or resume saved progress
|
|
65
|
+
tutorial run --restart <id> # discard saved progress and start over
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Review past runs
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
tutorial review <id>
|
|
72
|
+
tutorial review <id> --step 2
|
|
73
|
+
tutorial review <id> --run-id <run-id>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Trust author-supplied shell checks
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
tutorial run --allow-shell-checks <id>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
A tutorial step may declare a `check_command` that runs in your shell
|
|
83
|
+
to validate the step. This validation is opt-in: pass
|
|
84
|
+
`--allow-shell-checks` only when you trust the tutorial author.
|
|
85
|
+
|
|
86
|
+
## Writing tutorials
|
|
87
|
+
|
|
88
|
+
Take the interactive walkthrough first:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
tutorial run writing-tutorials
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### File format
|
|
95
|
+
|
|
96
|
+
A tutorial is a single Markdown file beginning with YAML front matter:
|
|
97
|
+
|
|
98
|
+
````markdown
|
|
99
|
+
---
|
|
100
|
+
id: my-tutorial
|
|
101
|
+
title: My Tutorial
|
|
102
|
+
summary: One-line description shown by `tutorial list`.
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
# First step
|
|
106
|
+
|
|
107
|
+
```tutorial-step
|
|
108
|
+
required_patterns:
|
|
109
|
+
- some-command
|
|
110
|
+
hint: Try running `some-command`.
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Step body in Markdown.
|
|
114
|
+
````
|
|
115
|
+
|
|
116
|
+
- Required front-matter fields: `id`, `title`, `summary`.
|
|
117
|
+
- Each top-level `# Heading` becomes one step.
|
|
118
|
+
- A step may begin with a fenced `tutorial-step` YAML block. Recognised
|
|
119
|
+
fields are `required_patterns`, `check_command`, `hint`, `edit_file`,
|
|
120
|
+
`kind`, `options`, and `answers`.
|
|
121
|
+
- Without `kind` or `edit_file`, a step opens an interactive shell.
|
|
122
|
+
- `edit_file` opens a workspace-relative file in `$EDITOR`, falling
|
|
123
|
+
back to `vim`, `vi`, or `nano` when `$EDITOR` is unset.
|
|
124
|
+
- `kind: input`, `kind: single_select`, and `kind: multi_select` prompt
|
|
125
|
+
directly in the CLI instead of opening a shell or editor. `input`
|
|
126
|
+
answers use the same string-or-`{mode, pattern}` format as
|
|
127
|
+
`required_patterns`; select questions use literal option text in
|
|
128
|
+
`options` and `answers`.
|
|
129
|
+
- `check_command` only runs when the reader passes
|
|
130
|
+
`--allow-shell-checks`.
|
|
131
|
+
|
|
132
|
+
### Share and install
|
|
133
|
+
|
|
134
|
+
Install a tutorial Markdown file or URL into the user's tutorial
|
|
135
|
+
directory:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
tutorial install path/to/tutorial.md
|
|
139
|
+
tutorial install https://example.com/tutorial.md
|
|
140
|
+
tutorial install --force path/to/tutorial.md
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Use `--force` to overwrite an installed tutorial with the same `id`.
|
|
144
|
+
The standalone CLI auto-loads installed tutorials alongside the
|
|
145
|
+
built-ins.
|
|
146
|
+
|
|
147
|
+
### Load ad hoc
|
|
148
|
+
|
|
149
|
+
To use a tutorial without installing it, point at the file or directory
|
|
150
|
+
on the command line:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
tutorial list --tutorial-path some/dir
|
|
154
|
+
tutorial run --tutorial-path some/dir <id>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`--tutorial-path` may be repeated and is appended after the built-ins.
|
|
158
|
+
|
|
159
|
+
## Embedding the CLI
|
|
160
|
+
|
|
161
|
+
The package can be mounted as a subcommand inside another Typer or
|
|
162
|
+
argparse application via `add_typer_subcommand` and
|
|
163
|
+
`add_argparse_subcommand` in `src/tutorial/cli.py`. Embedded hosts
|
|
164
|
+
prepend the `using-tutorials` lesson before host-specific tutorials, do
|
|
165
|
+
not load the user's installed tutorial directory, and hide the
|
|
166
|
+
standalone-only `install` command.
|
|
167
|
+
|
|
168
|
+
## Contributing
|
|
169
|
+
|
|
170
|
+
For the literate sources, the `make` build, and the repo layout, see
|
|
171
|
+
[`CONTRIBUTING.md`](CONTRIBUTING.md).
|
|
172
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
tutorial/__init__.py,sha256=eatCRqULsgRlm2__7DBJ3ki0YqWoffIVQcFT6-CYAic,1175
|
|
2
|
+
tutorial/catalog.py,sha256=3zUnKaIgkkOMVYLJXjcRtmGEg2sHxAJBjBY1VQeDYIQ,17643
|
|
3
|
+
tutorial/cli.py,sha256=K-q28ptUeXkPKlQXrdC_YBT077FEyQkmI8tUAqIK5iU,52421
|
|
4
|
+
tutorial/model.py,sha256=_cDPIfcZTT131abiUAAUZ8nXbxsQ8N-pCsXS0iqiMZM,1815
|
|
5
|
+
tutorial/run.py,sha256=jH1_UZUJ-p1JnA3o6zMJ3ryZmYKn4UgPeeR5a9k9BE0,21499
|
|
6
|
+
tutorial/shell.py,sha256=ed6tVBkEI_duJfGx5LItTu1QWO-RrnmWmn_2aeiDWF4,8867
|
|
7
|
+
tutorial/state.py,sha256=CGfO5UGzo0zWKLG0ZgGth6ljiUAH2rwpgzNtJRqekTA,6309
|
|
8
|
+
tutorial/tutorials/shell-basics.md,sha256=fpIwJ2YajzvOYzAeTm-yFF8-1k6GjFfD7AhOUwR0Ge8,2246
|
|
9
|
+
tutorial/tutorials/using-tutorials.md,sha256=qV4U3UgDErk02GB1aIWPlB6au8KfoatRx3rR25628Vw,6191
|
|
10
|
+
tutorial/tutorials/writing-tutorials.md,sha256=pkmwADpD6zAj2YPMnO9U3F63Gw78BNAuyclpKZF6bYg,10321
|
|
11
|
+
pytorial-0.1.dist-info/METADATA,sha256=t0NEy4ewqnKE4CDK6C4HWSEHWq1lw4KzM-OxErOMKe8,4495
|
|
12
|
+
pytorial-0.1.dist-info/WHEEL,sha256=Vz2fHgx6HFtSwhs8KvkHLqH5Ea4w1_rner5uNVGCeIE,88
|
|
13
|
+
pytorial-0.1.dist-info/entry_points.txt,sha256=sOFyYbyaassv0DyP9PS2I0LliYiImMPJsXYOYt3yGpQ,71
|
|
14
|
+
pytorial-0.1.dist-info/licenses/LICENSE,sha256=2Y2JY4tRQJtG0jXHpd6cYgeA-ce_JQ6lk8szzRanmU8,1068
|
|
15
|
+
pytorial-0.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Daniel Bosk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
tutorial/__init__.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Public package surface for ``tutorial``."""
|
|
2
|
+
|
|
3
|
+
from tutorial.cli import add_argparse_subcommand
|
|
4
|
+
from tutorial.cli import add_typer_subcommand
|
|
5
|
+
from tutorial.cli import app
|
|
6
|
+
from tutorial.cli import create_app
|
|
7
|
+
from tutorial.catalog import TutorialCatalog
|
|
8
|
+
from tutorial.catalog import get_tutorial
|
|
9
|
+
from tutorial.catalog import get_tutorials
|
|
10
|
+
from tutorial.model import StepTranscript
|
|
11
|
+
from tutorial.model import TextMatch
|
|
12
|
+
from tutorial.model import Tutorial
|
|
13
|
+
from tutorial.model import TutorialRun
|
|
14
|
+
from tutorial.model import TutorialStep
|
|
15
|
+
from tutorial.run import RunResult
|
|
16
|
+
from tutorial.run import TutorialRunner
|
|
17
|
+
from tutorial.shell import run_interactive_shell
|
|
18
|
+
from tutorial.shell import run_scripted_shell
|
|
19
|
+
from tutorial.state import ProgressState
|
|
20
|
+
from tutorial.state import StateStore
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"ProgressState",
|
|
24
|
+
"RunResult",
|
|
25
|
+
"StateStore",
|
|
26
|
+
"StepTranscript",
|
|
27
|
+
"TextMatch",
|
|
28
|
+
"Tutorial",
|
|
29
|
+
"TutorialCatalog",
|
|
30
|
+
"TutorialRun",
|
|
31
|
+
"TutorialRunner",
|
|
32
|
+
"TutorialStep",
|
|
33
|
+
"add_argparse_subcommand",
|
|
34
|
+
"add_typer_subcommand",
|
|
35
|
+
"app",
|
|
36
|
+
"create_app",
|
|
37
|
+
"get_tutorial",
|
|
38
|
+
"get_tutorials",
|
|
39
|
+
"run_interactive_shell",
|
|
40
|
+
"run_scripted_shell",
|
|
41
|
+
]
|