Runnable Files Demo

VERSION a9b38ce
Runnable Files Demo

A file node with an interpreter= is a runnable block whose code lives in a file instead of a fence: interpreter target runs the file, and the node behaves like a fence in every other way — deps=, env=, cache, confirm, meshfox:arg arguments, run history, run -d. See SPEC.md's "Node types" (the file entry) for the reference.

The block is always named after its node, so meshfox run <node> addresses it without a trailing block name. Cached output below is from actual meshfox run invocations (for example meshfox examples/runnable-files.canvas.md run hello), not typed by hand.

Hello

hello.sh

Plain case. The script runs in the canvas's own directory, not the script's: cwd below is examples, while the script lives one level deeper. The path in the link is resolved relative to the canvas and may not leave its tree (or the directories of dir/file variables).

exit code: 0 · 16ms

hello from hello.sh
cwd: examples
Shown as code

display="code" previews the script itself, so the node reads like a fence that happens to be backed by a file — the preview is read fresh from disk, and the block's fingerprint follows the file's content: edit the script and its cached output (and "already ran this session" freshness) goes stale. This node only previews and runs; the Arguments node below declares arguments for the same script.

import argparse
import os

parser = argparse.ArgumentParser()
parser.add_argument("--lang", default="en")
parser.add_argument("--pages", type=int, default=0)
args = parser.parse_args()

print(f"env:  lang={os.environ.get('lang', '-')} pages={os.environ.get('pages', '-')}")
print(f"argv: lang={args.lang} pages={args.pages}")
Dependencies

Any block can depend on a file node's block as node-id/node-id, and a file node can carry its own deps= on its meshfox:node line — the same attributes a fence puts in its info string (deps, env, cache, confirm, default, lease, defer, ...), minus name (always the node id), interpreter (its own attribute) and fold. They are only accepted on a file node that has an interpreter; meshfox validate rejects them anywhere else.

echo "pipeline done"
Prepare
Arguments

A file node declares arguments exactly like a fence — meshfox:arg lines — but they sit immediately above the link (nothing but blank lines between, the same rule as above a fence). Values reach the script two ways: as environment variables (always, like fence arguments) and as --name=value flags after the script path, in declaration order. python3 extract.py --lang=hy --pages=3 below also has lang and pages in its environment.

Extract

extract.py

Launched as an application: meshfox examples/runnable-files.canvas.md run arguments extract 'extract[lang=hy,pages=3]', from a manual form in the web UI/TUI, or as a dependency (deps='extract/extract[lang=hy]'). A block with arguments cannot use cache (cached output is kept per block, not per application), for file nodes and fences alike — meshfox validate says so. That run prints env: lang=hy pages=3 and argv: lang=hy pages=3 (copied from the terminal).

Environment only

report.sh

argv="false" keeps the flags off the command line for a script that does not parse them (an argparse script would reject unknown flags). The arguments are still in the environment, so meshfox ... run arguments report 'report[lang=hy]' prints report for lang=hy (argv: 0 extra arguments). Only blocks with an interpreter get flags; a plain bash fence has no script path to append them to and receives the environment only.

Confirmation

reset.sh

confirm works as on a fence: every invocation, including as someone else's dependency, needs explicit approval — meshfox ... run reset --confirm, the confirmation dialog in the web UI, y in the TUI.

Not supported
  • tty, service and tangle on a file node — the script is run directly from its file; meshfox validate rejects them.
  • cache together with arguments (see Extract).
  • More than one block per file node, or other fences in its body: the body is the link, an optional plain-prose caption, and — written by meshfox — one trailing cached-output region.