sudoblockio / tackle

Tackle is a programmable configuration language for building modular utilities, code generators, and CLIs with schema validation baked in.
Apache License 2.0
52 stars 2 forks source link

Command Arrow #164

Open robcxyz opened 1 year ago

robcxyz commented 1 year ago

It is very common to want to run a system command which tackle should make simple. Issue is the parser and general mechanics are not very elegant right now. Solution should be clean to make it on par with being able to create a Makefile.

Current

Single line->: command echo foo 
Multiple lines:
  ->: command 
  command: |
    echo foo1
    echo bar1

Currently broken

Single line->: command echo --foo 

Any args with a dash are parsed out

Single line->: command "echo --foo"

This works though

Multiple lines:
  ->: command 
    echo foo1
    echo bar1

Also this

Multiple lines->: command 
  echo foo 
  echo bar

But not this

Multiple lines->: command 
  echo --foo 
  echo bar

Approaches

Dollar Sign

call->: $echo foo bar 

Would require changes to the hook running qualifying each key. Also doesn't easily extend to how this could be done in the context of declarative hooks which should have a simple way of handling.

Bad idea...

New Arrow

This is probably the cleanest approach

public-declarative-hook<\: echo --foo bar 
private-declarative-hook</: echo --foo bar 
public-hook-call\>: echo --foo bar 
private-hook-call/>: echo --foo bar 
public-declarative-hook:
  <\: echo --foo bar 
  help: ...
private-declarative-hook:
  </: echo --foo bar 
  help: ...
public-hook-call:
  \>: echo --foo bar 
private-hook-call:
  />: echo --foo bar 
public-declarative-hook-call->: public-declarative-hook
private-declarative-hook-call_>: private-declarative-hook
multi line simple:
  <\: echo --foo bar 
    a new command foo --bar 
multi line inline<\: echo --foo bar 
  a new command foo --bar 
multi line symbol<\: |
  echo --foo bar 
  a new command foo --bar 
multi line simple:
  option: str 
  args: ['option']
  <\: echo --foo {{option}} 
    a new command foo --bar 

Best selling feature is the platform dependent call, something that we could implement in a hook but then that would be the only thing it would implement.

os<\: echo --foo bar
os<\linux: echo --foo bar
os<\mac: echo --foo bar
os<\win: echo --foo bar
os<\bsd: echo --foo bar
os<\:
  linux: echo --foo bar 
  mac: echo --foo bar 
  win: echo --foo bar 
  bsd: echo --foo bar
  _: echo --foo barr 
call|cmd->: echo foo --bar  
call|cmd_>: echo foo --bar 
call\>linux: echo foo --bar 

Would also need some lookup tables for platform names and clear docs on how which platform name applies to which. For instance linux vs ubuntu should internally resolve where we first try ubuntu then try linux.

Implementations

Alternative implementations would be too hacky most likely. Macros are an established pattern and can be hooked into the parsing logic easily.

Macros

Macros would be run on dicts / function dict inputs and hence would expand keys based on

Input:

os<\: echo --foo bar
os<\linux: echo --foo bar
os<\mac: echo --foo bar
os<\win: echo --foo bar
os<\bsd: echo --foo bar

tackle/macros/cmd_hook_flatten_macro

os<\:
  _: echo --foo barr 
  linux: echo --foo bar 
  mac: echo --foo bar 
  win: echo --foo bar 
  bsd: echo --foo bar

tackle/macros/cmd_hook_to_match_function_macro

os<-:
  return: do 
  exec: 
    do:
      ->: match 
      case: 
        linux/>: echo --foo bar 
#          ...
        _: ...

Note: This macro would then be used within the match hook so no need to run again within the tackle file import for dcl hooks

tackle/macros/cmd_hook_to_command_hook_macro

os<-:
  return: do 
  exec: 
    do:
      ->: match 
      case: 
        linux: 
          ->: command 
          command: echo --foo bar 
#          ...
        _: ...

Note: If running macro against a declarative hook's dict (ie embedded), this would then be exposed as a method on the declarative hook.