<div dir="ltr">FYI, <a href="https://twistedmatrix.com/trac/ticket/7907#ticket">https://twistedmatrix.com/trac/ticket/7907#ticket</a> created.<br></div><br><div class="gmail_quote">On Wed, May 20, 2015 at 7:31 PM Moshe Zadka <<a href="mailto:zadka.moshe@gmail.com">zadka.moshe@gmail.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi glyph and exarkun,<br><br>[1] The compose syntax is the least interesting part for me here, and seems to cause the most bike-shedding, so I think I will punt on that. Instead, I will write a function called "compose()" which can be used from .tac files or possibly other plug-ins, leaving the issue of the syntax for a different day.<div>[2] It seems like the biggest inconsistency in the docstrings is that they mention the parent without having an attribute for it. (E.g., the docstring for setServiceParent *says* "parent attribute is set", but there's no "parent attribute" in the interface. Glyph, if you want to open a ticket with the issues you found, please assign it to me -- otherwise, more specificity is useful!</div><div>[2a] Since the docstrings do refer to the parent attribute, and since I would be surprised if services just implemented the interface without inheriting from "Service", I wonder if people object *too* much if I "fix" it by documenting the parent attribute as part of the interface?</div><div>[3] I think that with the compose() function available in .tac files, maybe needing .tac *with* subcommands is not quite as important? Maybe I'll leave that off of the initial sprint.</div><div><br></div><div>So bottom line, current plans:</div><div>[4] Implement compose() as a function that takes an iterable-of-iterables, treats them as command-line arguments for services, and builds a MultiService() with them all.</div><div>[5] Document the parent attribute in IService (and possibly other issues, depending on Glyph opening a bug for [2]</div><div>[6] Implement provides() the way I wanted to (now that parent is documented)</div><div><br></div><div>Since it seems like compose-as-a-function is the least controversial bit here, I'll start with that while the other issues settle down.</div><div><br></div><div>Moshe Z.</div><div><br></div></div><br><div class="gmail_quote">On Wed, May 20, 2015 at 5:18 PM <<a href="mailto:exarkun@twistedmatrix.com" target="_blank">exarkun@twistedmatrix.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 07:29 pm, <a href="mailto:glyph@twistedmatrix.com" target="_blank">glyph@twistedmatrix.com</a> wrote:<br>
><br>
>>On May 20, 2015, at 04:13, <a href="mailto:exarkun@twistedmatrix.com" target="_blank">exarkun@twistedmatrix.com</a> wrote:<br>
>><br>
>>On 19 May, 09:01 pm, <a href="mailto:tom.prince@ualberta.net" target="_blank">tom.prince@ualberta.net</a> wrote:<br>
>>>Glyph <<a href="mailto:glyph@twistedmatrix.com" target="_blank">glyph@twistedmatrix.com</a>> writes:<br>
>>>>You could also find some other way to split the argument list but<br>
>>>>"+" doesn't seem particularly obscure in this context to me.  (If<br>
>>>>there's really a need to pass a literal "+" to a plugin we could add<br>
>>>>an escaping syntax as well.)<br>
>>><br>
>>>I think if we are adding syntax, then we should also add escaping at<br>
>>>the<br>
>>>same time.<br>
>>><br>
>>>On a related note, when designing this kind of syntax, I think it is<br>
>>>often valuable to explictly leave some of the space as an explict<br>
>>>error,<br>
>>>to leave freedom to extend the syntax in the future.<br>
>><br>
>>I think this is 100% correct.  This is part of why I don't want the<br>
>>syntax added to `Options`.  If it's a feature of, say, a "compose"<br>
>>twistd plugin then you can always throw the whole "compose" twistd<br>
>>plugin in the trash and start again.  That gives you quite a lot of<br>
>>space for syntax changes. :)<br>
>><br>
>>(And of course, not introducing a syntax at all leaves you even more<br>
>>room... but talking this crowd out of inventing weird syntaxes is<br>
>>probably an exercise in futility.)<br>
><br>
>Much as I love weird syntaxes, using "+" as a separator for a 'compose'<br>
>plugin seems about as straightforward as I could imagine such a thing<br>
>working.  Do you have an alternate proposal that is less 'weird'?  I<br>
>wouldn't promise to accept it but I wouldn't want to go with something<br>
>unnecessarily weird just due to a failure of my imagination.<br>
<br>
It's possible this is a case of necessary weirdness - at least, if<br>
you're dead-set on some kind of option-based CLI interface to this<br>
functionality.<br>
<br>
Think about other CLI tools that try to offer this kind of composition.<br>
Only two really come to mind for me and one of those is not exactly well<br>
regarded for its novel syntax (hint - it rhymes with "schmestreamer).<br>
<br>
This is not to say that this kind of composition is a bad thing - or<br>
even that no other widely-used software supports the kind of invoke-<br>
several-things-of-stuff behavior that we're talking about providing<br>
access to here.<br>
<br>
However, I do think it is the case that most of the world tries to solve<br>
this problem without trying to force everything into a world-view framed<br>
by GNU getopt().<br>
<br>
With that in mind, here are some alternatives:<br>
<br>
  (0) The null proposal<br>
<br>
    $ twistd compose \<br>
        web --port 80 +<br>
        manhole --auth foo + \<br>
        logging --path /var/run<br>
<br>
  (1) Borrow `--` which already means "stop parsing options here".  It<br>
makes sense if you think about sub-commands as existing on a stack and<br>
`--` meaning "pop the stack".  Possibly not actually feasible since I<br>
think `Options` already knows what `--` means (by virtue of actually<br>
*using* getopt()) and uses it to separate options from positional<br>
arguments (and therefore it's not an unambiguous separator - but I<br>
haven't double-checked this).<br>
<br>
    $ twistd compose \<br>
        web --port 80 -- \<br>
        manhole --auth foo -- \<br>
        logging --path /var/run<br>
<br>
  (2) Put things into strings which already have well-defined escape<br>
syntax:<br>
<br>
    $ twistd compose \<br>
        'web --port 80' \<br>
        'manhole --auth foo' \<br>
        'logging --path /var/run'<br>
<br>
  (3) Load things from a file (really just a variation on (2)):<br>
<br>
    $ cat myapp.compose<br>
    web --port 80<br>
    manhole --auth foo<br>
    logging --path /var/run<br>
    $ twistd compose myapp.compose<br>
<br>
Note these aren't really syntax ideas.  Apart from (1), they're ideas<br>
for not needing a new syntax.  As soon as you actually invent a new<br>
syntax you invite comments like "Well, maybe you should use `;` instead<br>
of `+` because `;` is already kind of ingrained as a separator and<br>
people are used to having to escape it" (which, see, I put in quotes,<br>
because I'm totally not saying that, even if it is totally true) to<br>
which you can only really reply that your gut agrees or your gut<br>
disagrees and it's always a bummer when the best support you have for<br>
some programming decision is some gut feeling you had.<br>
<br>
I might actually be somewhat attracted to (3) because:<br>
<br>
  * I don't really want to build up giant piles of configuration on my<br>
command line and then rely on my shell history for being able to find it<br>
again.  myapp.compose is something I could even put in my version<br>
control system.<br>
<br>
  * Despite shell quoting and escaping rules being perfectly well<br>
defined, I'd really much rather not have to deal with an automatic extra<br>
layer of quotes.<br>
<br>
And a last point to consider about new syntaxes - what are the security<br>
considerations of a command like:<br>
<br>
    $ twistd compose \<br>
        web --port ${WEB_PORT} +<br>
        manhole --auth foo + \<br>
        logging --path /var/run<br>
<br>
I'll grant there's a bug there (the shell variable should be quoted -<br>
but I only know one person who consistently gets that right).<br>
<br>
Regardless, I think any proposal would greatly benefit from a much<br>
greater consideration of use-cases and examples than I've yet seen<br>
discussed in this thread.<br>
<br>
Jean-Paul<br>
<br>
_______________________________________________<br>
Twisted-Python mailing list<br>
<a href="mailto:Twisted-Python@twistedmatrix.com" target="_blank">Twisted-Python@twistedmatrix.com</a><br>
<a href="http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python" target="_blank">http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python</a><br>
</blockquote></div></blockquote></div>