Skip to content

Commit

Permalink
[hay] Two hay evaluation modes.
Browse files Browse the repository at this point in the history
- Within 'hay eval' and eval_hay(): basic sandboxing.
  - You can call procs, hay nodes, or echo/write/use.
- At the top level: there is no sandboxing.
  - You can get the result with _hay()
  - Maybe this goes within proc _main later?

The non-sandboxed kind should be useful for associating metadata with
procs?  But I guess you can't use eval_hay() on it, because that's also
sandboxed.

Might need to tweak these rules.

This is part of #951.
  • Loading branch information
Andy C committed Jun 11, 2022
1 parent 5de2f83 commit f9193a5
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 19 deletions.
23 changes: 20 additions & 3 deletions core/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,15 +215,32 @@ def RunSimpleCommand(self, cmd_val, cmd_st, do_fork, call_procs=True):
status = self.cmd_ev.RunProc(proc_node, argv[1:], arg0_spid)
return status

# Notes:
# - procs shadow hay names
# - hay names shadow normal builtins? Should we limit to CAPS or no?
if self.hay_state.Resolve(arg0):
return self.RunBuiltin(builtin_i.haynode, cmd_val)

builtin_id = consts.LookupNormalBuiltin(arg0)

if self.exec_opts._running_hay():
# Hay: limit the builtins that can be run
# - declare 'use dialect'
# - echo and write for debugging
# - no JSON?
if builtin_id in (
builtin_i.haynode, builtin_i.use, builtin_i.echo, builtin_i.write):
cmd_st.show_code = True # this is a "leaf" for errors
return self.RunBuiltin(builtin_id, cmd_val)

self.errfmt.Print_('Unknown command %r while running hay' % arg0,
span_id=arg0_spid)
return 127

if builtin_id != consts.NO_INDEX:
cmd_st.show_code = True # this is a "leaf" for errors
return self.RunBuiltin(builtin_id, cmd_val)

if self.exec_opts._running_hay() and self.hay_state.Resolve(arg0):
return self.RunBuiltin(builtin_i.haynode, cmd_val)

environ = self.mem.GetExported() # Include temporary variables

if cmd_val.typed_args:
Expand Down
12 changes: 8 additions & 4 deletions core/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,6 @@ def __init__(self):
self.cur_defs = self.root_defs # Same as ClearDefs()
self.def_stack = [self.root_defs]

# same as ClearResult()
node = self._MakeOutputNode()
self.result_stack = [node] # type: List[Dict[str, Any]]
self.output = None # type: Dict[str, Any]
Expand All @@ -357,15 +356,20 @@ def _MakeOutputNode(self):

def PushEval(self):
# type: () -> None
self.output = None # clear it to make sure

# remove previous results
node = self._MakeOutputNode()
self.result_stack = [node]

self.output = None # remove last reuslt

def PopEval(self):
# type: () -> None

# Save it
# Save the result
self.output = self.result_stack[0]

# Now reset
# Clear results
node = self._MakeOutputNode()
self.result_stack = [node]

Expand Down
89 changes: 78 additions & 11 deletions spec/hay.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,32 +101,100 @@ hay eval :foo {
echo bar
}
}
## status: 1
## status: 127
## STDOUT:
foo
## END

#### hay names only visible in 'hay eval' block
shopt --set parse_brace
#### hay names at top level
shopt --set parse_brace parse_at
shopt --unset errexit

hay define package
hay define Package

package cppunit
Package one
echo status=$?

setvar args = _hay()['children'][0]['args']
write --sep ' ' $len(_hay()['children']) @args

hay eval :result {
package cppunit
Package two
echo status=$?
}

package cppunit
setvar args = result['children'][0]['args']
write --sep ' ' $len(result['children']) @args

Package three
echo status=$?

setvar args = _hay()['children'][0]['args']
write --sep ' ' $len(_hay()['children']) $[_hay()['children'][0]['args'][0]]

## STDOUT:
status=127
status=0
status=127
1 one
status=0
1 two
status=0
1 three
## END

#### builtins an externals not available in hay eval
shopt --set parse_brace
shopt --unset errexit

hay define Package

try {
hay eval :result {
Package foo {
/bin/ls
}
}
}
echo "status $_status"

try {
hay eval :result {
cd /tmp
}
}
echo "status $_status"

## STDOUT:
status 127
status 127
## END

#### procs in hay eval
shopt --set parse_brace parse_at parse_proc

hay define Package

proc outside {
echo outside
Package OUT
}

hay eval :result {
outside

proc inside {
echo inside
}

inside
}

const args = result['children'][0]['args']
write --sep ' ' -- $len(result['children']) @args

## STDOUT:
outside
inside
1 OUT
## END

#### hay eval attr node, and JSON
Expand Down Expand Up @@ -420,6 +488,7 @@ foo bar
shopt --set oil:all parse_equals

hay define package
hay define deps/package

hay eval :result {

Expand All @@ -430,8 +499,6 @@ hay eval :result {
echo "backup = https://archive.example.com/$URL_PATH"
}

hay define deps/package

# Note: PushTemp() happens here
deps spam {
# OVERRIDE
Expand Down
2 changes: 1 addition & 1 deletion test/parse-errors.sh
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ oil_expr_more() {
oil_hay_assign() {
set +o errexit

if _is-oil-native; then
if is-oil-native; then
return
fi

Expand Down

0 comments on commit f9193a5

Please sign in to comment.