ewels / rich-click

Format click help output nicely with rich.
https://ewels.github.io/rich-click/
MIT License
630 stars 36 forks source link

Test help output in `rich-click` CLI is robust to lazy loading of modules. #160

Open dwreeves opened 9 months ago

dwreeves commented 9 months ago

TLDR: it's missing the subcommands.

celery --help:

Usage: celery [OPTIONS] COMMAND [ARGS]...

  Celery command entrypoint.

Options:
  -A, --app APPLICATION
  -b, --broker TEXT
  --result-backend TEXT
  --loader TEXT
  --config TEXT
  --workdir PATH
  -C, --no-color
  -q, --quiet
  --version
  --skip-checks          Skip Django core checks on startup. Setting the
                         SKIP_CHECKS environment variable to any non-empty
                         string will have the same effect.
  --help                 Show this message and exit.

Commands:
  amqp     AMQP Administration Shell.
  beat     Start the beat periodic task scheduler.
  call     Call a task by name.
  control  Workers remote control.
  events   Event-stream utilities.
  graph    The ``celery graph`` command.
  inspect  Inspect the worker at runtime.
  list     Get info from broker.
  logtool  The ``celery logtool`` command.
  migrate  Migrate tasks from one broker to another.
  multi    Start multiple worker instances.
  purge    Erase all messages from all known task queues.
  report   Shows information useful to include in bug-reports.
  result   Print the return value for a given task id.
  shell    Start shell session with convenient access to celery symbols.
  status   Show list of workers that are online.
  upgrade  Perform upgrade between versions.
  worker   Start worker instance.

rich-click celery --help:


 Usage: celery [OPTIONS] COMMAND [ARGS]...                                                          

 Celery command entrypoint.                                                                         

╭─ Options ────────────────────────────────────────────────────────────────────────────────────────╮
│ --app             -A  APPLICATION                                                                │
│ --broker          -b  TEXT                                                                       │
│ --result-backend      TEXT                                                                       │
│ --loader              TEXT                                                                       │
│ --config              TEXT                                                                       │
│ --workdir             PATH                                                                       │
│ --no-color        -C                                                                             │
│ --quiet           -q                                                                             │
│ --version                                                                                        │
│ --skip-checks                      Skip Django core checks on startup. Setting the SKIP_CHECKS   │
│                                    environment variable to any non-empty string will have the    │
│                                    same effect.                                                  │
│ --help                             Show this message and exit.                                   │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
dwreeves commented 9 months ago

Ah it gets worse. celery beat --help:

Usage: celery beat [OPTIONS]

  Start the beat periodic task scheduler.

Beat Options:
  --detach                        Detach and run in the background as a
                                  daemon.
  -s, --schedule TEXT             Path to the schedule database.  Defaults to
                                  `celerybeat-schedule`.The extension '.db'
                                  may be appended to the filename.
  -S, --scheduler TEXT            Scheduler class to use.
  --max-interval INTEGER          Max seconds to sleep between schedule
                                  iterations.
  -l, --loglevel [DEBUG|INFO|WARNING|ERROR|CRITICAL|FATAL]
                                  Logging level.

Daemonization Options:
  -f, --logfile TEXT  Log destination; defaults to stderr
  --pidfile TEXT
  --uid TEXT
  --gid TEXT
  --umask TEXT
  --executable TEXT

Options:
  --help  Show this message and exit.

rich-click celery beat --help:


 Usage: celery beat [OPTIONS]                                                                       

 Start the beat periodic task scheduler.                                                            

Beat Options:

  --detach

Detach and run in the background as a daemon.

  -s, --schedule TEXT

Path to the schedule database.  Defaults to `celerybeat-

                                  schedule`.The extension '.db' may be appended to the filename.

  -S, --scheduler TEXT

Scheduler class to use.

  --max-interval INTEGER

Max seconds to sleep between schedule iterations.

  -l, --loglevel [DEBUG|INFO|WARNING|ERROR|CRITICAL|FATAL]

Logging level.

Daemonization Options:

  -f, --logfile TEXT

Log destination; defaults to stderr

  --pidfile TEXT

  --uid TEXT

  --gid TEXT

  --umask TEXT

  --executable TEXT

Options:

  --help

Show this message and exit.

Note this is specific to 1.8.0dev. 1.7.3 does not have this issue. I have a feeling why that is the case, but I will have to look deeper.

dwreeves commented 9 months ago

Figured out what's going on pretty quickly with the subcommand and I'll have a fix for that, but the main command I will have to dig into.

dwreeves commented 9 months ago

Ahhh, figured it out. TLDR, this is a bug in 1.8.0dev, and it arises due to the order of how Click stuff is loaded now with the lazy-loading.

This is entirely fixable, and in that sense it's not a big deal.

What is a big deal is this is a big pain to safeguard against in tests, since the tests all share the same sys.modules and the same click module, normally invoked test cases of click Groups will contain false passes. I need to think about how to guard against this!