pallet / stevedore

A shell script embedding in clojure
93 stars 14 forks source link

Link jclouds/pallet OS keywords with Script language #9

Closed frenchy64 closed 5 years ago

frenchy64 commented 13 years ago

Now we dispatch on scripting language, a thin layer between defscripts and stevedore core is needed to link OS keywords to the relevant scripting language.

eg. :ubuntu => bash :windows => batch :centos => bash

hugoduncan commented 13 years ago

Should this be part of stevedore? How about if you are running zsh on ubuntu?

frenchy64 commented 13 years ago

Now that we have multiple output languages, I don't think it's appropriate for defscript/defimpl to only dispatch on OS. It should also dispatch on scripting languages.

ie. Dispatch on [*stevedore-impl* *script-context*]

For example:

(script/defscript declare-arguments [& args])
(script/defimpl declare-arguments [:pallet.stevedore.batch :default]
  [& args]
  ... )
(script/defimpl declare-arguments [:pallet.stevedore.bash [:redhat]]
  [& args]
  ... )
(script/defimpl declare-arguments [:pallet.stevedore.bash [:ubuntu :centos]]
  [& args]
  ... )
(script/defimpl declare-arguments [:pallet.stevedore.zsh [:ubuntu]]
  [& args]
  ... )

I'm not certain how to approach implementation inheritance. zsh and bash implementations will often overlap, for example. We could use a similar "best-match" like *script-context*, with a vector of compatible languages.

(script/defimpl declare-arguments [[:pallet.stevedore.zsh :pallet.stevedore.bash] [:ubuntu]]
  [& args]
  ... )

I'm unsure whether implementation inheritance via derive is a good idea here (for `stevedore-impl values). Would come in handy for :bash3 and :bash4 similarities and similar situations.

I'm also not too sure whether it's a good idea to change the existing defscript/defimpl scheme or whether we should add a separate function. It would be straightforward to convert any existing implementations, as they are all for bash.

I've been thinking about this problem for awhile but this just popped up today. Thoughts?

hugoduncan commented 13 years ago

If stevedore is already abstracting over script language, is there really a need to dispatch on language again?

I see that doing so would allow you to have different algorithms for different shells, but wonder how often that would be useful or required.

If we do decide it is required, is there need to do any more than include the language (and possibly a simplified classification of shell) in the existing script-context?

frenchy64 commented 13 years ago

I'm starting to see that it's redundant dispatching twice, as you suggested. I forgot defscripts should emit unprocessed stevedore DSL, instead of raw string output in the dispatched language.

The main reason for this proposal is the distinction between function calls (really just goto) and system commands in batch.

As per a previous discussion, I have linked the Clojure function call syntax with batch function calls.

ie.

(with-stevedore-impl ::batch
  (script
    (ls)))
=> "call:ls"

As of now, there is no specific syntax to call external commands like dir or ping in Batch. Obviously, this isn't a problem with bash, as functions = commands syntactically.

So the current state:

(script/defscript ls [])
(script/defimpl declare-arguments :default]
  []
  (ls))
(script/defimpl declare-arguments :windows]
  []
  (dir))

(with-stevedore-impl ::bash
  (script
    (~ls)))
=> "ls"

(with-stevedore-impl ::bash
  (script
    (~ls)))
=> "call:dir" <- should be "dir"

So we need some extra syntax either for function calls or internal commands.

The workaround would be to treat defimpl as a string generator rather than a stevedore generator.

(script/defimpl declare-arguments :windows]
  []
  "dir"))

If I had to propose something, maybe (sys ls) for external commands and (ls) for local functions.

I can't see any way around it other than cheating and generating strings.