Open kablamo opened 9 years ago
Hi @kablamo
if this is possible without changing the current behaviour we welcome any patches. There is already a task on the backlog (without a ticket yet) to refactor the argument parsing. Maybe we can do this together in one step. Maybe there is a nice CPAN module that can do this?
Currently Rex (sort of) allows you to do more than one task at a time. So for example:
rex -G group task1 task2
task1 runs for each server in "group". However task2 seems to run on the local machine only.
I want to only allow Rex to do one task at a time. So in the above example, the string "task2" would get passed as an argument to task1 (in some backwards compatible way) and task2 would not run.
Does that count as changing current behavior? <-- The part about only doing one task at a time, I mean.
Hmm after reading some more of the documentation I think that would count as breaking backwards compatibility.
I'm interested in getting involved in refactoring argument parsing. What specific goals did you have in mind?
One way to break backwards compatibility without affecting any users would be to create a new command line util with a different name. Or maybe just something that wraps the 'rex' script.
Well,
i think we can add a new feature flag for example 1.3
(if the new arg parser is part of version 1.3) which will enable this new arg parser. So there is no problem for people who are using an older feature flag. This would be a little bit of a hack, because currently the arguments are parsed before the Rexfile is parsed. So we would ne to parse the Rexfile twice. The first time to check which feature flag is enabled, then parse the arguments and then load the Rexfile for real.
Another option would be to try to autodetect which parser should be used (i would vote for this one).
For example if we define that we wan't to have a more generic cli interface:
Syntax:
rex $action @options
To execute a task
rex execute $task
rex execute $task -u user -p password --foo=bar --action=fun
To query modules.rexify.org
rex search apache
To download a module from modules.rexify.org, git, ...
rex download https://github.com/RexOps/rex-apache.git
Or to publish a module to modules.rexify.org (or a private rex recipes repository)
rex publish
To create a new Rex project:
rex new MyProject
@ferki What do you think?
And
rex tasks [topic]
The clarity and flexibility are really tempting. I was initially wanting this. But its so much work to type rex execute
. rex
is nice and short. I have mixed feelings about it. Another thought is to keep rex
usage very simple and put all those subcommands into another script called rex-control
or something. I'm not sure.
well, i think the new parser can also handle rex $task
so that the short version will work :)
So then you wouldn't be able to name any of your tasks tasks, new, publish, download, search, or execute. Or rather you could, but you would have to use the rex execute
to do them
I find those ideas interesting, but I need some more time to think about them. I also believe that we started to talk about 2 or 3 smaller problems instead of a single big one.
So, i just started with implementing a new cli parser that is based on MooX::Cmd and MooX::Options.
I have pushed the current code state to my private repo: https://github.com/krimdomu/Rex/tree/feature/new-cli/lib/Rex/CLI
An example can be found in this other branch which is adding Rex-Overlord commands. (Rex-Overlord will be a rex server)
https://github.com/krimdomu/Rex/tree/feature/overlord/lib/Rex/CLI
What this is technically doing is this:
With PPI the rex
command (https://github.com/krimdomu/Rex/blob/feature/new-cli/bin/rex) first try to detect if the cli_v2
feature should be activated.
This is done in Rex::DetectCLI::detect_cli
(https://github.com/krimdomu/Rex/blob/feature/new-cli/lib/Rex/DetectCLI.pm). This function returns which version of the cli parser rex shoud load.
With this we can now write a new cli parser without compromising already running Rex installations and give people the time to migrate to the new cli as soon as we decide to make the new cli the default one.
Awesome. I was going to do that. I'll take a look
I've pushed the feature/new-cli
branch to this repository. So it is easier to contribute to it.
I've been thinking about the command line UI too. I"ve been trying to evolve the current cli to something that works like this:
rex task # execute task on localhost
rex namespace:task # execute namespace:task on localhost
rex task option=value # execute task with options
rex task arg1 # execute task with arguments
rex task arg1 option=value # execute task with arguments and options
rex -H host task option=value # execute task on a host
rex -G group task arg1 arg2 # execute task on a group
rex -H host task1 arg1 arg2 task2 option=value # task chaining
rex tasks # list tasks
rex batches # list batches
rex environments # list environments
rex groups # list groups
rex sometask -h # show usage for a task
One thought I keep having is that the root level namespace should be reserved for subcommands and all user created tasks should live somewhere else.
@kablamo yes this looks good. and also the idea with the root level namespace. i think it would be good to have it this way, because then we can custom commands to it. Like migrating all the rexify
commands.
And it would be cool to have the ability to extend these root-level commands with custom plugins.
rex project Foo # to create a new project
rex search foo # to search online for a module named foo
rex use Foo # download Foo module and install it into lib folder
rex webserver # to start a webserver for the current project for a webui
rex some-other-interessting-stuff
...
Edit: grmpf i wrote nearly the same thing a few comments above :D
I'd like to limit the number of tasks Rex can do at a time to 1. That way all arguments after the task name can be passed to the task. For example:
would result in `-l /etc' being passed to the task Unix::ls() in some way. The only way to do this currently is to do something really awkward like:
How would you feel about a pull request that did something like this? I realize there are a lot of details that need to be worked out here.