К основному содержанию
правило

click — правило для Cursor: что делает и как установить

Правило задаёт рекомендации по созданию CLI на Python с библиотекой click. Помогает организовать команды, параметры, вывод и подсказки.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/click.mdc
Открыть на GitHub

Что делает click

Правило охватывает структуру проекта с каталогом src и группами команд, выбор между аргументами и опциями, типизацию и текст справки. Для вывода оно рекомендует click.echo и click.secho вместо print(); это важно, если CLI должен корректно обрабатывать Unicode и форматирование на разных платформах.

Файл .cursor/rules/click.mdc применяется к файлам **/*.py. В проекте с одной командой рекомендации по модульной структуре могут оказаться избыточными; для нетривиального CLI правило предлагает разделять точку входа и команды. В показанных примерах используется Python и click.

Какие задачи решает

  • разнести команды CLI по модулям
  • отделить обязательные аргументы от необязательных параметров
  • добавить типы для аргументов и опций
  • выводить сообщения через click.echo или click.secho
  • сделать справку CLI понятнее с примерами использования

Примеры запросов агенту

  • Перестрой CLI на Python с click: вынеси команды из одного файла в модули.
  • Проверь, где уместны позиционные аргументы, а где опции для CLI на click.
  • Добавь типизацию и улучши вывод справки для команд click.

Как установить click

Вручную: положить файлы

.cursor/rules/click.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Вопросы о click

Как установить click в Cursor?

Добавь файл правила по пути .cursor/rules/click.mdc. Он применяется к файлам **/*.py.

Что делает правило click?

Оно направляет работу над CLI на Python с библиотекой click: структуру команд, аргументы и опции, вывод, типизацию и справку.

Как правило предлагает организовать команды click?

Для нетривиального CLI оно рекомендует структуру src, отдельную точку входа и команды, сгруппированные через click.Group. В небольшом проекте такая модульность может быть лишней.

Исходный текст

click.mdc · CC0-1.0
---
description: This guide outlines definitive best practices for building robust, maintainable, and user-friendly command-line interfaces (CLIs) using the `click` Python library, emphasizing modern patterns and common pitfalls.
globs: **/*.py
---
# click Best Practices

`click` is the undisputed standard for building Python CLIs. Follow these rules to ensure your tools are consistent, maintainable, and a joy to use.

## 1. Code Organization & Structure

For any non-trivial CLI, structure your project to promote modularity and testability. Always use a `src` layout.

### ✅ GOOD: Modular `src` Layout

Separate your main CLI entry point from individual commands. Use `click.Group` to organize subcommands into logical modules.

```python
# src/mycli/__init__.py
import click
from .commands.greet import greet_command
from .commands.config import config_group

@click.group()
@click.version_option(version="1.0.0")
@click.pass_context
def cli(ctx: click.Context) -> None:
    """My Awesome CLI Tool."""
    ctx.ensure_object(dict) # Initialize context object
    # Any global setup or configuration can go here

cli.add_command(greet_command)
cli.add_command(config_group)

# src/mycli/commands/greet.py
import click

@click.command(name="greet")
@click.argument("name", type=str)
@click.option("--formal", is_flag=True, help="Use a formal greeting.")
def greet_command(name: str, formal: bool) -> None:
    """Greets the given NAME."""
    if formal:
        click.secho(f"Greetings, {name}!", fg="blue")
    else:
        click.echo(f"Hello, {name}!")

# src/mycli/commands/config.py
import click

@click.group(name="config")
def config_group() -> None:
    """Manage configuration settings."""
    pass

@config_group.command(name="set")
@click.argument("key", type=str)
@click.argument("value", type=str)
def config_set(key: str, value: str) -> None:
    """Set a configuration KEY to VALUE."""
    click.echo(f"Setting '{key}' to '{value}'")

@config_group.command(name="get")
@click.argument("key", type=str)
def config_get(key: str) -> None:
    """Get the value of a configuration KEY."""
    click.echo(f"Getting value for '{key}'")
```

### ❌ BAD: Monolithic `cli.py`

Avoid dumping all commands and logic into a single file. This quickly becomes unmanageable.

```python
# cli.py (BAD)
import click

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

@cli.command()
@click.argument("name")
def greet(name): # Logic for greet command
    click.echo(f"Hello {name}!")

@cli.command()
@click.argument("key")
@click.argument("value")
def config_set(key, value): # Logic for config set command
    click.echo(f"Setting {key} to {value}")
```

## 2. Argument Parsing: Arguments vs. Options

Follow `click`'s conventions:
*   **Arguments**: Positional, required values.
*   **Options**: Flag-based, optional settings.

### ✅ GOOD: Clear Distinction

```python
import click

@click.command()
@click.argument("input_file", type=click.Path(exists=True)) # Positional, required file
@click.option("--output", "-o", type=click.Path(), help="Output file path.") # Optional flag
@click.option("--force", is_flag=True, help="Overwrite existing output.") # Flag without value
def process(input_file: str, output: str | None, force: bool) -> None:
    """Processes INPUT_FILE with optional OUTPUT."""
    click.echo(f"Processing {input_file}...")
    if output:
        click.echo(f"Outputting to {output} (Force: {force})")
```

### ❌ BAD: Misusing Arguments for Optional Settings

Using positional arguments for optional values makes `help` output confusing and usage less intuitive.

```python
import click

@click.command()
@click.argument("input_file")
@click.argument("output_file", required=False) # BAD: Optional positional argument
def process_bad(input_file: str, output_file: str | None) -> None:
    """Processes INPUT_FILE. Can optionally specify OUTPUT_FILE."""
    # This makes the CLI harder to use and read.
    click.echo(f"Input: {input_file}, Output: {output_file}")
```

## 3. Output: `click.echo` and `click.secho`

**Always** use `click.echo` or `click.secho` instead of `print()`. This ensures consistent Unicode handling and proper styling across all platforms, especially Windows.

### ✅ GOOD: Platform-Agnostic, Styled Output

```python
import click

@click.command()
def log_messages() -> None:
    """Demonstrates various output types."""
    click.echo("This is a standard message.")
    click.secho("This is an important warning!", fg="yellow", err=True) # To stderr, colored
    click.secho("Success!", fg="green", bold=True)
    click.echo(f"Unicode support: こんにちは世界") # Works everywhere
```

### ❌ BAD: Inconsistent Output

`print()` lacks cross-platform Unicode support and styling capabilities.

```python
import click

@click.command()
def log_messages_bad() -> None:
    """Demonstrates bad output types."""
    print("This message might break on Windows terminals with unicode.") # BAD
    print("\033[91mThis is a red error. (Manual ANSI codes are fragile)\033[0m") # BAD
```

## 4. Type Hints

Mandatory. Use Python's type hints with `click`'s built-in types (e.g., `click.Path`, `click.File`) for robust validation and improved IDE support.

### ✅ GOOD: Fully Type-Hinted

```python
import click
from typing import TextIO

@click.command()
@click.argument("count", type=int)
@click.option("--name", type=str, default="World")
@click.option("--config", type=click.Path(exists=True, dir_okay=False), help="Path to config file.")
@click.option("--output", type=click.File("w"), help="Output stream.")
def greet_typed(count: int, name: str, config: str | None, output: TextIO | None) -> None:
    """Greets NAME COUNT times."""
    for _ in range(count):
        (output or click.get_text_stream("stdout")).write(f"Hello, {name}!\n")
    if config:
        click.echo(f"Using config from: {config}")
```

### ❌ BAD: Untyped Parameters

Lack of type hints makes code harder to understand, validate, and refactor.

```python
import click

@click.command()
@click.argument("count") # BAD: No type hint
@click.option("--name", default="World") # BAD: No type hint
def greet_untyped(count, name):
    """Greets NAME COUNT times."""
    # Type errors will only appear at runtime
    for _ in range(int(count)):
        click.echo(f"Hello, {name}!")
```

## 5. Comprehensive Help Text & Examples

Good help text is crucial. Always provide a concise summary, detailed explanations for options, and practical usage examples.

### ✅ GOOD: Detailed Help with Examples

```python
import click

@click.command()
@click.argument("source", type=click.Path(exists=True))
@click.argument("destination", type=click.Path())
@click.option("--recursive", "-r", is_flag=True, help="Copy directories recursively.")
@click.option("--force", "-f", is_flag=True, help="Overwrite existing files without prompting.")
def copy(source: str, destination: str, recursive: bool, force: bool) -> None:
    """
    Copies files or directories from SOURCE to DESTINATION.

    Examples:
        \b
        # Copy a single file
        mycli copy file.txt backup/file.txt

        # Copy a directory recursively
        mycli copy -r my_dir backup/my_dir

        # Force overwrite a file
        mycli copy -f important.log /var/log/important.log
    """
    click.echo(f"Copying '{source}' to '{destination}' (Recursive: {recursive}, Force: {force})")
```

### ❌ BAD: Minimalist Help Text

Vague help text leaves users guessing.

```python
import click

@click.command()
@click.argument("source")
@click.argument("destination")
@click.option("--recursive", "-r", is_flag=True) # BAD: No help text
def copy_bad(source: str, destination: str, recursive: bool) -> None:
    """Copies things.""" # BAD: Vague summary
    click.echo(f"Copying {source} to {destination}")
```

## 6. Packaging with `pyproject.toml`

Distribute your CLI tools reliably using `pyproject.toml` for metadata and entry points. This is the modern Python packaging standard.

```toml
# pyproject.toml
[project]
name = "mycli"
version = "1.0.0"
description = "My Awesome CLI Tool"
requires-python = ">=3.10"
dependencies = [
    "click>=8.3.1",
]

[project.scripts]
mycli = "mycli:cli" # Maps 'mycli' command to 'src/mycli/__init__.py:cli'
```

Install with `pipx install .` for isolated execution.

## 7. Testing with `CliRunner`

Automated testing is non-negotiable. Use `click.testing.CliRunner` to simulate CLI invocations and assert outputs.

```python
# tests/test_cli.py
from click.testing import CliRunner
from mycli import cli # Assuming 'mycli' is installed or in PYTHONPATH

def test_greet_command() -> None:
    runner = CliRunner()
    result = runner.invoke(cli, ["greet", "Alice"])
    assert result.exit_code == 0
    assert "Hello, Alice!" in result.output

def test_greet_formal_option() -> None:
    runner = CliRunner()
    result = runner.invoke(cli, ["greet", "Bob", "--formal"])
    assert result.exit_code == 0
    assert "Greetings, Bob!" in result.output
    assert "blue" in result.output # Check for color codes if applicable
```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Похожие правила IDE

Все правила IDE по теме «Языки программирования» →
cli-anything HKUDS Строит Python-харнесс с Click-командами для любого GUI-приложения или репозитория. Генерирует REPL, тесты и документацию по методологии CLI-Anything. CX Codex +1 2 100установок cli-developer https://github.com/Jeffallan Скилл для разработки командной строки: помогает строить CLI-инструменты с парсингом флагов, интерактивными подсказками, прогресс-барами и автодополнением в bash/zsh/fish. Работает с commander, click, typer и cobra. CX Codex +1 4 800установок click-test-plan Owl-Listener Помогает спланировать клик-тесты: где люди кликают первым делом и находят ли нужное в навигации. Пригодится, когда макет уже есть, а проверить его нечем. CX Codex +1 2 000установок api-gateway maton Направляет запросы к сторонним сервисам через шлюз Maton с автоматической подстановкой ключей. Пригодится для работы с почтой, CRM или таблицами прямо из агента. CX Codex +1 1 300установок dotnet-inspect richlander Скилл собирает факты о .NET-пакетах, библиотеках и API вместо догадок: что внутри, какие зависимости, чем отличаются версии. CX Codex +1 510установок football-data machina-sports Скилл даёт агенту данные о футболе: таблицы, расписание, статистику матчей, xG, трансферы и прогнозы. Ключи API не нужны. CX Codex +1 2 300установок

Из того же набора240

Весь набор →
css Задаёт стандарты вёрстки для Cursor: модульную структуру Sass, именование по БЭМ, переменные и производительную анимацию. Пригодится для поддержки чистоты в стилях. ★ 3 580звёзд репо crewai Правило для Python-файлов подсказывает Cursor, как организовать CrewAI: разделять агентов, задачи и оркестрацию, а также передавать контекст между задачами. ★ 3 580звёзд репо codemirror Правило для Cursor задаёт, как писать редакторы на CodeMirror 6: модульные импорты, неизменяемое состояние, конфигурация через расширения. ★ 3 580звёзд репо cloudflare Задаёт стандарты разработки под Cloudflare Workers и Pages в Cursor. Помогает писать stateless-код для edge-рантайма, подключать базы данных и следить за размером бандла. ★ 3 580звёзд репо clerk Правило для Cursor задаёт жёсткие требования к аутентификации Clerk: PKCE, серверные проверки, короткие токены. Пригодится, когда в проекте уже есть Clerk и нужен порядок в безопасности. ★ 3 580звёзд репо circleci Задаёт стандарты оформления пайплайнов CircleCI в проекте. Помогает генерировать надёжные конфигурации с кэшированием, reusable-командами и параллельными тестами. ★ 3 580звёзд репо cheerio Правило задаёт практики для cheerio в Node.js: структура скрейперов, выбор селекторов, очистка данных и тесты. ★ 3 580звёзд репо chakra-ui Правило для Cursor задаёт, как писать интерфейсы на Chakra UI v2: тема через токены, варианты компонентов через рецепты, стилевые пропсы вместо CSS. ★ 3 580звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой