Reputation: 2591
I am new to python & fabric. I have a python module module1.py which would like to take in a command parameter, we use argparse inside the module1.py to require a command line parameter. But we are trying to run the whole program through fabric, if I directly specify the command line when running through fab, I got
mycode.py: error: argument --config_yaml is required
How could I pass the argument through fab?
Thanks!
Upvotes: 2
Views: 512
Reputation: 6808
From what i can see from here:
https://github.com/fabric/fabric/blob/master/fabric/main.py#L340 https://github.com/fabric/fabric/blob/master/fabric/main.py#L619
You CAN'T do it. You can't add things to env_options
before main.py runs, your code inside fabfile.py
will run after main()
has already been processed.
You can however do this:
Rename fabfile.py
-> whatever you want as long as its not fabric.py
. I called mine fabricc.py
from fabric.state import env_options, make_option
env_options.append(make_option('--myconfig', dest='config_file', default='default.ini'))
from fabric import main
from fabric.api import task, env
@task
def do_something():
print('config file: {}'.format(env.config_file))
if __name__ == '__main__':
main.find_fabfile = lambda x: __file__
main.main()
now run it:
$ python fabricc.py do_something
config file: default.ini
Done.
or..
$ python fabricc.py do_something --myconfig=somethinelse.ini
config file: somethinelse.ini
Done.
Word of warning DO NOT call it --config
-- this is a builtin param.
With this you still enjoy everything you still love about fabric
and nothing has changed.
$ python fabricc.py do_something --help
Usage: fab [options] <command>[:arg1,arg2=val2,host=foo,hosts='h1;h2',...] ...
Options:
-h, --help show this help message and exit
-d NAME, --display=NAME
...
-z INT, --pool-size=INT
number of concurrent processes to use in parallel mode
--myconfig=CONFIG_FILE
PS. i dont suggest you do the fabric override to handle it manually. Im just showing you it can be done. (the reason i dont condone this is: compatibility. If the version changes tomorrow this might break) best to use the product how the author meant it to be used.
====================================================================
Also, fabric is meant to be a fancy orm builder -- for lack of a better word. You cannot have command line arguments on a per-task-basis, it wasnt design to work like that. BUT it was designed to take in task-function arguments:
@task
def do_something(file=None):
print('config file: {}'.format(file or 'default.ini'))
$ fab dosomething:test
config file: override.ini
Done.
and that is what fabric was created to do.
its meant to be used like this:
@task
def environment(box_env=None):
...
@task
def deploy(branch='master'):
...
@task
def provision(recreate_if_existing=False, start_nignx=True):
...
fab evironment:dev deploy:development
fab evironment:dev provision:True,False
all together.
fab evironment:dev provision deploy:development
Upvotes: 1
Reputation: 231385
I know argparse
, but not fabric
. From the error is looks like your script defines a '--config_yaml' argparse
argument (and makes it 'required'). But fabric
apparently also uses that argument name.
I don't know if fabric
also uses argparse
. But it is common for programs like that to strip off the commandline arguments that it expects, and pass the rest on to your code.
Do you need to use --config_yaml
in your script? And why is it set to required=True
? argparse
allows you to specify a required
parameter, but ideally flagged arguments like this are optional. If not given they should have a reasonable default.
I see a --config=...
argument in the fabric
API, but not a --config_yaml
.
I wonder if this section about per-task arguments is relevant
http://docs.fabfile.org/en/1.10/usage/fab.html#per-task-arguments
It sounds like you need to add the task name to the argument. fabric
doesn't just pass all unknown arguments to the task (which is what I was assuming above). But I don't have fabric
installed, so can't test it.
Upvotes: 0