Укажите либо STDIN, либо опцию пути к файлу для Python Нажмите сценарий CLI - PullRequest
0 голосов
/ 20 января 2020

Я пытаюсь щелкнуть в первый раз, но наткнулся на камень преткновения.

Я хочу, чтобы мои (две) подкоманды принимали опцию пути к файлу или accept содержимое файла из STDIN.

  • Разрешено: использовать путь для --compose-file

    ./docker-secret-helper.py secret-hash-ini --compose-file docker-compose-test.yml
    
  • Разрешено: использовать содержимое файла as stdin

    cat docker-compose-test.yml | ./docker-secret-helper.py secret-hash-ini
    

    (Должна ли быть опция для указания stdin, например, -i или что-то еще?)

  • Не разрешено: Ни один --compose -file или stdin передано

    ./docker-secret-helper.py secret-hash-ini
    

    Должно возвращать что-то вроде: You must either pass --compose-file or pipe in stdin.

Текущий скрипт

Мой текущий скрипт принимает (только) путь к файлу (через --compose-file):

#!/usr/bin/env python

import click
from DockerSecretHelper import DockerSecretHelper

CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])

@click.group(context_settings=CONTEXT_SETTINGS)
def cli():
    pass

@cli.command(help="retrieves an ini-style file of variables to be used as env vars for docker-compose commmand")
@click.option('--compose-file', help='compose file to work with', required=True)
def secret_hash_ini(**kwargs):
    helper = DockerSecretHelper()
    print(helper.get_secret_hash_ini_format_from_compose_file(**kwargs))
    # will need some kind of if block to call helper.get_secret_hash_ini_format_from_compose_contents(**kwargs) in the
    #  case of stdin

@cli.command(help="retrieves names/values of external secrets; to be used by `docker secret set`")
@click.option('--compose-file', help='compose file to work with', required=True)
def external_secret_info_json(**kwargs):
    helper = DockerSecretHelper()
    print(helper.get_external_secret_info_as_json_from_compost_file(**kwargs))
    # will need some kind of if block to call helper.get_external_secret_info_as_json_from_compose_contents(**kwargs) in
    # the case of stdin

if __name__ == '__main__':
    cli()

Как реализовать или применить STDIN или путь к файлу (но не оба).

I ' Я открыт для изменений в синтаксисе моей команды, чтобы лучше следовать потенциальным соглашениям.

Этот вопрос похож на Создание приложения командной строки в python с использованием Click , поэтому может предоставить некоторые строительные блоки (которые у меня возникают проблемы при сборке).

1 Ответ

2 голосов
/ 20 января 2020

Я бы использовал тип опции клика File:

import click
import sys


@click.group()
def cli():
    pass


@cli.command()
@click.option('--compose-file', 
              help='compose file to work with',
              type=click.File('r'),
              default=sys.stdin)
def secret_hash_ini(compose_file):
    with compose_file:
        data = compose_file.read()

    print(data)


if __name__ == '__main__':
    cli()

Предполагая, что у нас есть файл example.txt, содержащий текст:

This is a test.

Затем мы можем указать файл с --compose-file:

$ python docker-secret-helper.py secret-hash-ini --compose-file example.txt
This is a test.

Или мы можем прочитать из stdin:

$ python docker-secret-helper.py secret-hash-ini < example.txt
This is a test.

Мы не можем сгенерировать ошибку в случае, если "Ни то, ни другое --compose-file ни stdin прошел ", потому что stdin всегда доступен. Если мы вызываем docker-secret-helper.py без предоставления --compose-file и без перенаправления stdin, он просто зависнет в ожидании ввода.

...