Python + getopt — Проблемы с парсингом

У меня возникли проблемы с написанием кода Геррита http://code.google.com/p/gerrit/ крючки.

http://gerrit.googlecode.com/svn/documentation/2.2.0/config-hooks.html

Если я проанализирую командную строку для patchset-created --change --change-url --project --branch --uploader --commit --patchset

def main():

if (len(sys.argv) < 2):
    showUsage()
    exit()

if (sys.argv[1] == 'update-projects'):
    updateProjects()
    exit()

need = ['action=', 'change=', 'change-url=', 'commit=', 'project=', 'branch=', 'uploader=',
        'patchset=', 'abandoner=', 'reason=', 'submitter=', 'comment=', 'CRVW=', 'VRIF=' , 'patchset=' , 'restorer=', 'author=']
print  sys.argv[1:]
print '-----' 
optlist, args = getopt.getopt(sys.argv[1:], '', need)
id = url = hash = who = comment = reason =  codeReview = verified = restorer = ''
print optlist

for o, a in optlist:
    if o == '--change': id = a
    elif o == '--change-url': url = a
    elif o == '--commit': hash = a
    elif o == '--action': what = a
    elif o == '--uploader': who = a
    elif o == '--submitter': who = a
    elif o == '--abandoner': who = a
    elif o == '--author' : who = a
    elif o == '--branch': branch = a
    elif o == '--comment': comment = a
    elif o == '--CRVW' : codeReview = a
    elif o == '--VRIF' : verified = a
    elif o == '--patchset' : patchset = a
    elif o == '--restorer' : who = a
    elif o == '--reason' : reason = a

Ввод командной строки:

--change I87f7802d438d5640779daa9ac8196aeb3eec8c2a
--change-url http://<hostname>:8080/308
--project private/bar
--branch master
--uploader xxxxxxx-xxxxx xxxxxxx ([email protected])
--commit 49aae9befaf27a5fede51b498f0660199f47b899 --patchset 1

напечатать sys.argv[1:]

['--action', 'new',
'--change','I87f7802d438d5640779daa9ac8196aeb3eec8c2a',
'--change-url',
'http://<hostname>:8080/308',
'--project', 'private/bar',
'--branch', 'master',
'--uploader', 'xxxxxxx-xxxxx', 'xxxxxxx', '([email protected])',
'--commit', '49aae9befaf27a5fede51b498f0660199f47b899',
'--patchset', '1']

распечатать оптлист

[('--action', 'new'),
('--change', 'I87f7802d438d5640779daa9ac8196aeb3eec8c2a'),
('--change-url', 'http://<hostname>:8080/308'),
('--project', 'private/bar'),
('--branch', 'master'),
('--uploader', 'xxxxxxx-xxxxx')]

Я не знаю, почему скрипт генерирует

'--uploader', 'xxxxxxx-xxxxx', 'xxxxxxx', '([email protected])'
and not
'--uploader', 'xxxxxxx-xxxxx xxxxxxx ([email protected])'

потому что скрипт не анализирует --commit --patchset...

Когда я разбираю добавленный комментарий, все работает:

Ввод командной строки:

   -change I87f7802d438d5640779daa9ac8196aeb3eec8c2a
   --change-url http://<hostname>.intra:8080/308
   --project private/bar
   --branch master
   --author xxxxxxx-xxxxx xxxxxxx ([email protected])
   --commit 49aae9befaf27a5fede51b498f0660199f47b899
   --comment asdf
   --CRVW 0 
   --VRIF 0

напечатать sys.argv[1:]

  '--action', 'comment',
    '--change', 'I87f7802d438d5640779daa9ac8196aeb3eec8c2a',
    '--change-url',
    'http://<hostname>:8080/308',
    '--project', 'private/bar',
    '--branch', 'master',
    '--author', 'xxxxxxx-xxxxx xxxxxxx ([email protected])', <<< That's right!
    '--commit', '49aae9befaf27a5fede51b498f0660199f47b899',
    '--comment', 'asdf',
    '--CRVW', '0',
    '--VRIF', '0']

person Philippxp    schedule 08.11.2011    source источник


Ответы (3)


Поскольку имена и значения опций разделены пробелами, вы должны поместить значения в кавычки, если они сами содержат пробелы.

Если вы напишете --uploader xxxxxxx-xxxxx xxxxxxx ([email protected]), последние две строки окажутся на args из строки

optlist, args = getopt.getopt(sys.argv[1:], '', need)

поскольку они не связаны с --uploader

person wutz    schedule 08.11.2011

Вы должны указать аргумент, если он содержит пробелы, как и для всех инструментов командной строки:

--uploader "xxxxxxx-xxxxx xxxxxxx ([email protected])"
person neurino    schedule 08.11.2011
comment
Я получаю этот поток от Геррита, но зачем работать с этим, когда Геррит использует комментарии с добавлением... В этом проблема, которую я не понимаю - person Philippxp; 08.11.2011
comment
Почему бы вам просто не сделать ' '.join(a) с аргументами для --uploader? Я полагаю, Геррит делает то же самое. Это не так сложно. - person neurino; 08.11.2011
comment
Теперь я перемещаю аргументы перед запуском скрипта, и этот обходной путь работает. - person Philippxp; 10.11.2011

Вы также можете рассмотреть возможность использования gnu_getopt(), так как это позволит вам смешивать опциональные и не опциональные аргументы. Из Документация

Функция getopt() прекращает обработку параметров, как только встречается аргумент, не являющийся параметром.

Если вы используете gnu_getopt, остальные параметры, а именно commit и pathset, все равно будут правильно проанализированы, даже если в аргументе загрузчика отсутствуют кавычки.

person RedBaron    schedule 08.11.2011
comment
Спасибо. Это хороший намек, но это не вариант, мне нужны все аргументы. - person Philippxp; 10.11.2011