-
-
Notifications
You must be signed in to change notification settings - Fork 163
OSH Builtins: "Hello, world!" Example
This document describes the steps required to create a fictional OSH builtin called hw
that prints "Hello, world!" when invoked.
Code changes are shown using the git-diff(1)
command, so that the reader has all the information to understand:
-
Which files were modified (filepaths)
-
How files were modified (content changes)
-
Where files were modified (line numbers)
Create Spec Test
spec/builtin-hw.test.sh
-----------------------
#!/bin/bash
#### `hw` prints "Hello, world!"
hw
## status: 0
## STDOUT:
Hello, world!
## END
-
The "####" directive provides a test title
-
From the end of this line until the start of the next "##" is a command block containing commands to be executed in top-down order. In this case, there is a single command to execute:
hw
-
The first occurrence of the "##" directive asserts that the exit status code of the command block, after being executed, must be 0
-
The second occurrence of the "##" directive asserts that the standard output of the command block, after being executed, must be "Hello, world!"
-
The last occurrence of the "##" directive marks the end of the individual spec test
Now, we'll update the test harness with a new directive called "builtin-hw" that will run the hw
spec test
$> git diff test/spec.sh
diff --git a/test/spec.sh b/test/spec.sh
index 9ea7d710..2e4559f6 100755
--- a/test/spec.sh
+++ b/test/spec.sh
@@ -432,6 +432,10 @@ builtin-times() {
sh-spec spec/builtin-times.test.sh $BASH $ZSH $OSH_LIST "$@"
}
+builtin-hw() {
+ sh-spec spec/builtin-hw.test.sh $OSH_LIST "$@"
+}
+
command-parsing() {
sh-spec spec/command-parsing.test.sh ${REF_SHELLS[@]} $OSH_LIST "$@"
}
$> test/spec.sh builtin-hw
builtin-hw.test.sh
case line osh
0 3 FAIL `hw` prints "Hello, world!"
FATAL: 1 tests failed (1 osh failures)
Update OSH ASDL
The OSH ASDL uses a list of builtins to produce compiler artifacts. We'll need to add a hw
enumerated type to this list
$> git diff osh/runtime.asdl
diff --git a/osh/runtime.asdl b/osh/runtime.asdl
index 238e4eab..1014124b 100644
--- a/osh/runtime.asdl
+++ b/osh/runtime.asdl
@@ -3,7 +3,7 @@
module runtime
{
builtin =
- NONE | TIMES | READ | ECHO | PRINTF | SHIFT
+ NONE | HW | TIMES | READ | ECHO | PRINTF | SHIFT
| CD | PWD | PUSHD | POPD | DIRS
| EXPORT | READONLY | LOCAL | DECLARE | TYPESET
| UNSET | SET | SHOPT
$> git diff bin/oil.py
diff --git a/bin/oil.py b/bin/oil.py
index 443470c9..b61195f4 100755
--- a/bin/oil.py
+++ b/bin/oil.py
@@ -446,6 +446,7 @@ def ShellMain(lang, argv0, argv, login_shell):
builtin_e.DIRS: builtin.Dirs(mem, dir_stack, errfmt),
builtin_e.PWD: builtin.Pwd(mem, errfmt),
+ builtin_e.HW: builtin.Hw(),
builtin_e.TIMES: builtin.Times(),
builtin_e.READ: builtin.Read(splitter, mem),
builtin_e.HELP: builtin.Help(loader, errfmt),
$> git diff osh/builtin.py
diff --git a/osh/builtin.py b/osh/builtin.py
index f22c09c0..d68c14ca 100755
--- a/osh/builtin.py
+++ b/osh/builtin.py
@@ -89,6 +89,7 @@ _SPECIAL_ASSIGN_BUILTINS = {
}
_NORMAL_BUILTINS = {
+ "hw": builtin_e.HW,
"read": builtin_e.READ,
"echo": builtin_e.ECHO,
"printf": builtin_e.PRINTF,
@@ -739,3 +740,12 @@ class History(object):
item = readline_mod.get_history_item(i)
print('%5d %s' % (i, item))
return 0
+
+HW_SPEC = _Register('hw')
+class Hw(object):
+ def __init__(self):
+ pass
+
+ def __call__(self, arg_vec):
+ print("Hello, world!")
+ return 0
Rebuild osh
$> build/dev.sh all
[...]
$> test/spec.sh builtin-hw
builtin-hw.test.sh
case line osh
0 3 pass `hw` prints "Hello, world!"