Meneruskan parameter ke tugas fabric

123

Bagaimana cara mengirimkan parameter ke tugas fabric saat memanggil "fab" dari baris perintah? Sebagai contoh:

def task(something=''):
    print "You said %s" % something
$ fab task "hello"
You said hello

Done.

Apakah mungkin melakukan ini tanpa disuruh fabric.operations.prompt?

Donovan
sumber

Jawaban:

207

Dokumentasi argumen tugas Fabric 2:

http://docs.pyinvoke.org/en/latest/concepts/invoking-tasks.html#task-command-line-arguments


Fabric 1.X menggunakan sintaks berikut untuk meneruskan argumen ke tugas:

 fab task:'hello world'
 fab task:something='hello'
 fab task:foo=99,bar=True
 fab task:foo,bar

Anda dapat membaca lebih lanjut tentang ini di dokumen Fabric .

Jakub Roztocil
sumber
9
Kutipan tidak perlu; semua argumen adalah string: "karena proses ini melibatkan penguraian string, semua nilai akan berakhir sebagai string Python, jadi rencanakan dengan semestinya. (Kami berharap dapat memperbaikinya di versi Fabric mendatang, asalkan sintaks intuitif dapat ditemukan.)"
Carl G
4
Kutipan di sekitar hello worldtampaknya perlu?
PEZ
2
@PEZ Jika itu benar, kutipan mungkin diperlukan dalam contoh itu karena terminal atau parser baris perintah fabric akan melihat spasi dan berpikir bahwa itu adalah akhir dari segalanya untuk tugas itu dan itu worldadalah tugas baru.
Adam Kerz
1
Selain itu, setelah menggunakan ini selama kurang dari satu menit, saya telah menemukan bahwa, di Windows, menggunakan tanda kutip tunggal menghasilkan tanda kutip tunggal yang diteruskan sebagai bagian dari argumen, tetapi tanda kutip ganda dihapus terlebih dahulu. Jadi, 'hello world'akan menghasilkan string Python 'hello world', tetapi "hello world"akan menghasilkan hello world(yang mungkin diinginkan kebanyakan orang).
Adam Kerz
5
Karena proses ini melibatkan penguraian string, bar=Truedalam perintah fabric akan diteruskan sebagai bar='True'yang bukan nilai boolean
Programmer Kimia
7

Argumen fabric dipahami dengan penguraian string yang sangat dasar, jadi Anda harus sedikit berhati-hati dalam mengirimnya.

Berikut adalah beberapa contoh cara berbeda untuk meneruskan argumen ke fungsi pengujian berikut:

@task
def test(*args, **kwargs):
    print("args:", args)
    print("named args:", kwargs)

$ fab "test:hello world"
('args:', ('hello world',))
('named args:', {})

$ fab "test:hello,world"
('args:', ('hello', 'world'))
('named args:', {})

$ fab "test:message=hello world"
('args:', ())
('named args:', {'message': 'hello world'})

$ fab "test:message=message \= hello\, world"
('args:', ())
('named args:', {'message': 'message = hello, world'})

Saya menggunakan kutipan ganda di sini untuk mengeluarkan shell dari persamaan, tetapi tanda kutip tunggal mungkin lebih baik untuk beberapa platform. Perhatikan juga pelarian untuk karakter yang dianggap sebagai pembatas oleh fabric.

Detail lebih lanjut di dokumen: http://docs.fabfile.org/en/1.14/usage/fab.html#per-task-arguments

Bogdan Kiselitsa
sumber
7

Di Fabric 2, cukup tambahkan argumen ke fungsi tugas Anda. Misalnya, untuk meneruskan versionargumen ke tugas deploy:

@task
def deploy(context, version):
    ...

Jalankan sebagai berikut:

fab -H host deploy --version v1.2.3

Fabric bahkan mendokumentasikan opsi secara otomatis:

$ fab --help deploy
Usage: fab [--core-opts] deploy [--options] [other tasks here ...]

Docstring:
  none

Options:
  -v STRING, --version=STRING
mrts
sumber
apakah ada cara untuk mendefinisikan host dalam fungsi itu sendiri? Mirip dengan tag @roles () di mana kita dapat menentukan daftar host untuk menjalankan tugas.
Anish
2

Anda harus meneruskan semua variabel Python sebagai string, terutama jika Anda menggunakan sub-proses untuk menjalankan skrip, atau Anda akan mendapatkan error. Anda perlu mengubah variabel kembali menjadi tipe int / boolean secara terpisah.

def print_this(var):
    print str(var)

fab print_this:'hello world'
fab print_this='hello'
fab print_this:'99'
fab print_this='True'
frage
sumber
1

Jika seseorang ingin meneruskan parameter dari satu tugas ke tugas lain di fabric2, cukup gunakan kamus lingkungan untuk itu:

@task
def qa(ctx):
  ctx.config.run.env['counter'] = 22
  ctx.config.run.env['conn'] = Connection('qa_host')

@task
def sign(ctx):
  print(ctx.config.run.env['counter'])
  conn = ctx.config.run.env['conn']
  conn.run('touch mike_was_here.txt')

Dan lari:

fab2 qa sign
MikeL
sumber