mkdocs / get-deps

An extra command for MkDocs that infers required PyPI packages from `plugins` in mkdocs.yml
MIT License
1 stars 0 forks source link

Extra dependencies conditioned by configuration values #1

Open pawamoy opened 3 weeks ago

pawamoy commented 3 weeks ago

Currently, in the catalog, we have this entry for mkdocstrings:

- name: mkdocstrings
  mkdocs_plugin: mkdocstrings
  extra_dependencies:
    plugins.mkdocstrings.handlers.crystal: mkdocstrings-crystal
    plugins.mkdocstrings.handlers.python: mkdocstrings-python
  github_id: mkdocstrings/mkdocstrings
  pypi_id: mkdocstrings
  labels: [plugin]
  category: api-docs

The extra dependencies config means that if we find a plugins.mkdocstrings.handlers.crystal key in the config, mkdocstrings-crystal should be installed, etc..

Two other examples:

# markdown-exec entry
extra_dependencies:
  plugins.markdown-exec.ansi: markdown-exec[ansi]
# mkdocs-material entry
extra_dependencies:
  plugins.social: mkdocs-material[imaging]

Here we use the same mechanism to list extras.

However in the second example (markdown-exec), the extra should actually be conditioned by the value of the plugins.markdown-exec.ansi config: markdown-exec supports values "required", "off", "auto", true and false (and other YAML boolean variants). The [ansi] extra should only be listed when the value is "required" or true (with "auto", which is the default value, we suppose that users are not aware of the ANSI feature and do not use it).

What I suggest is that we allow to specify the values that condition the addition of extra dependencies, something like:

extra_dependencies:
  plugins.markdown-exec.ansi:
    required: markdown-exec[ansi]
    true: markdown-exec[ansi]

Such a feature will also be useful for inferring extra dependencies needed when two specific config values are found. For example, in mkdocstrings-python we may want to decouple templates from the Python code (see https://github.com/mkdocstrings/python/issues/152). In that case, we would want get-deps to infer that mkdocstrings-python-material is needed when both the plugins.mkdocstrings.handlers.python is found and the theme.name value is equal to "material". In that case though we need a yet more complex syntax, of which I'm still unsure :thinking::

extra_dependencies:
  # possible extra dependency mkdocstrings-python-material installed when...
  mkdocstrings-python-material:
    # ...the plugins.mkdocstrings.handlers.python key is present
    - plugins.mkdocstrings.handlers.python
    # ...and when the theme.name value is equal to "material"
    - theme.name: material 

Notice how the key and values were reversed here, compared to the previous example and current behavior. Maybe we can reverse the previous suggestion too?

extra_dependencies:
  # possible extra dependency markdown-exec[ansi] installed when...
  markdown-exec[ansi]:
    # ...the plugins.markdown-exec.ansi value is equal to...
    - plugins.markdown-exec.ansi:
      # ...either "required" or true
      - required
      - true

Note how in the mkdocstrings case, the dependency conditions are AND'ed, and in the markdown-exec case, condition values are OR'ed. Both cases are compatible. Example using both:

extra_dependencies:
  # possible extra dependency foo installed when...
  foo:
    # ...the extra.bar key is present
    - extra.bar
    # ...and the extra.baz value is equal to 1, 2, or 3...
    - extra.baz: [1, 2, 3]
    # ...and the extra.qux value is present or equal to foo
    - extra.qux: [null, foo]
pawamoy commented 3 weeks ago

This syntax probably does not allow everything to be expressed, but we don't have a lot of extra dependencies conditionals like that in the ecosystem, so I think it's fine for now. But maybe we want to make the syntax super explicit and more expressive, to directly cater to more future uses:

extra_dependencies:
  # multiple deps supported with the same conditions
  - dependencies: [foo]
    conditions:
    - and:  # explicit AND, could be `or` too
      - extra.bar
      - extra.baz: [1, 2, 3]
      - extra.qux: [null, foo]