Open andychu opened 3 years ago
Config Dialect Use cases -- MOVED TO https://github.com/oilshell/oil/wiki/Config-Dialect
Naming idea: evalcows()
Just to recap:
core/pure.py
, but core/cows.py
?shopt parse_equals
shopt dynamic_scope
idea:
# eval-config.oil
proc server(name, &b) {
push-context route { # define route
var d = evalblock(b)
}
}
dialect --name myproject -- server otherproc {
source $1 # the filename ? Does it give good errors?
}
# config.cows
use dialect myproject # ensure it's running under this dialect
server www.example.com {
root = '/'
port = 80
}
Idea for evalblock()
semantics
x = 42
, but not var y = 43
.Does value_t
need a span_id then? I think I would find that useful in some cases, like the dynamic const check? If it's already defined?
Instead of evalblock()
, we have #1025
From Zulip, an idea to make blocks syntactic sugar for dicts, and then gracefully allow more validation with procs:
However I'd still like to define the valid first words, so you could have
eval ('myfile.oil', procs=%(package user))
And then 'package' and 'user' could be ways to define dicts, like
package cppunit
user bob
would turn into
{ "type": "package",
"name": "cppunit"
}
{ "type": "user",
"name": "bob"
}
New minimal idea (in NOTES.txt)
shvar PATH=''
to disable externals -- fix hash -d
bugpush-procs
to bring in procs from old namespace to new
parse_file(path Str) Block
eval_to_dict (block command_t)
-- see evaluation rules below
_ append(_config->users, 'bob')
-- we'll probably need a variant to append or CREATE _config->users
_config
get passed to procs? Is it a magic variable? what about nested evaluation of configs?{"type": "package", "name": "arg1"}
transformationsIs that it?
Issue for later:
parse_file()
and so forth.Evaluation rules:
EvalBlockToNamespace
, which is command_t
-> Dict[Str, Obj]
command_t
block_to_string()
functionMore isolation issues:
source
builtin shouldn't be able to open random files!parse_config()
function too!Doh so we need to restrict the builtins dictionary ...
Or we can rely on containers to do this?
It is an argument for always forking a process ... But then how do we get procs from one place to the other?
I think we don't want push-procs
. I think we want to have an inherent source
before the config file evaluation
bin/oven --source mydialect.oil -- myconfig.oil
It's a bit more complicated that way but probably more general and secure ... we don't want a blacklisting approach; whitelisting is better.
Although push-procs
is whitelisting of procs -- it's not whitelisting of builtins like source
though
Although Executor
holds both self.builtins
and self.procs
, so we could have
push (builtins = %(echo printf json), procs=%(foo bar)) {
shvar PATH='' {
const d = eval_to_dict(myblock)
}
}
First cut of hay
works! After a huge commit
https://github.com/oilshell/oil/commit/47c972391969bf59d9d421abad81bfdae74019e2
More:
child.block
and child.code_str
shell_code_str
or oil_code_str
depending on string or blockoil:all
-- important! Test it outhay define package/user package/resources
hay eval :result { }
-- for INLINE hay
shopt --set hay_eval
or something? The haynode
builtin can set it_hay()
is only for the interactive shell -- although slightly redundant with hay pp result
. Maybe undocumented?hay eval
hay eval
Related issues
block_as_str()
must do itparse_equals
inside .oil
files? #1139 source
and parse_hay()
and need to close the fileMore:
ctx_Temp
which is like FOO=bar
. Also hay eval
does.doc/hay.md
should have a quick startAfter some usage and feedback:
hay bind Package/TASK myproc_TASK
?
@ARGV
and a b Block
?shopt --set sandbox_{redirect,extern,source}
? (under group sandbox:all
?)
hay eval
?Had a look into the new doc/hay skeleton, and as you have mentioned DSLs there, and I still had your comment about the common push / pop issue in mind (https://github.com/oilshell/oil/issues/1059#issuecomment-1151734946), I felt maybe there is some common solution there to find.
Ruby/crystal seems to have two types of blocks for DSLs:
The difference between using do ... end and { ... } is that do ... end binds to the left-most call, while { ... } binds to the right-most call. The reason for this is to allow creating Domain Specific Languages (DSLs) using do ... end to have them be read as plain English: [...] You wouldn't want the above to be: [...] (https://crystal-lang.org/reference/1.4/syntax_and_semantics/blocks_and_procs.html)
Maybe some kind of general apply/with/to/do or and? -block might help for DSLs, too?
Yeah there is definitely possibility of things like that ... though I want people to use it first, and actually hit the problem, before we add complexity!
I'm pretty happy with the simple first pass, and hopefully we'll get a bunch of feedback on it
This feature is a bit more obscure than others, because I think platforms / maintainers will generally use it, not end users. i.e. it's for people building something like sourcehut, Github Actions, systemd, podman/Docker, etc.
Sure, a universal/left/right block application idea/rules will likely need some time to ripe anyway.
I had thought hay could be nice even just for exposing simplest config files to users, thanks to the sandboxing, safe to "source", no need to write parsing code? But I didn't grasp the whole usage/practical picture just yet.
Something in your latest "Sketches of YSH Features" blog and your intention for ysh to be well-extensible by users, made me remember my comments here. You wrote:
[proc] Arguments are bound left to right, with splats like ... picking up the rest, except for the block argument. It's always the last argument, so it's neither positional or named.
This sounds as if it wouldn't allow to pass multiple blocks.
I'm not sure if that would still allow for exposing/allowing for more generic block usage, i.e. having left and right binding blocks (for better readable DSLs https://github.com/oilshell/oil/issues/951#issuecomment-1152953400), as well as making use of hay-based config in ysh itself (e.g. no fuzz readable redirection syntax https://github.com/oilshell/oil/issues/1059#issuecomment-1137481928), and generic apply {...} to {...} block application or "operators".
With code+data in the blocks (i.e. hay) could that maybe be a useful basis to allow for implementing, e.g. said matrix algebra operators etc., as extensions as ysh libraries instead of compiled code?
I think you can only pass on block in the {}
style, as the last arg
But there's nothing stopping you from passing multiple blocks the expression style, like
myproc (block1, block2)
It's mainly a syntactic limitation
But yeah when we implement that, we should have some test cases for it
Summary: YAML alternative / COWS: configuration in Oil without Side effects
This is part of #631: Oil Blocks
Rough sketch of what we need:
evalblock()
functionPushTemp()
andPopTemp()
?blockstring()
function? I noticed this need for source/hut travis inline shellshopt --set dynamic_scope
?shopt --set parse_equals
-- this is NO LONGER a synonym for constsetvar
without a correspondingvar
??? Inside a block.Example of evalblock
How does scope work?