Overview

Artifact ID: d81dd77bb1608dfb0ef5a936c763b9b68f6aa22462671f16e6a49b20e023ac99
Page Name:Rationale
Date: 2018-07-04 13:53:59
Original User: mario
Mimetype:text/x-markdown
Parent: 16fae529a679fca600ff4d7b426e68b25c10449ee1e0836efb80e78dcc83518b (diff)
Content

Purpose

Plugin meta data is intended for basic code extension schemes.

  • Primary target are scripting languages.

  • Where "plugins" can be contained within a single source file.

  • It's just about the meta comment format however. There's no inherent definition on how to tie application-level callback / hook / class APIs.

  • Maintenance is simplified by having technical and description attributes embedded.

  • Foremost it's very discoverable and useful to end-users.

  • Extensibility is a core feature. (This spec is just to define some obvious standard fields.)

  • And while that's not a goal, even can help with application packaging.

Design Rationale

To make this suitable across programming languages, the syntax needed to be generic and not be tied to specific docblock variants.

  • Hence a consecutive # block is recommended as default comment style.

    • Individual implementations are encouraged to support any alternative comment block syntaxes.
  • key: value fields are a rather obvious choice. And they're already used in related specs (PKG-INFO, Debian control, etc.)

  • Key names should be single words:, or RFC message-header: combinations at most.

    • They should never contain spaces, as that made it really cumbersome to parse/process. (→ And that's how you get ants!)
    • In some languages it's a rather unfortunate idiom to use "ASCII art"-style comments. Often there's all sorts of personal variations like "Written by:" or "Authored by:" and so on - due to lack of standardization and language ecosystem.
    • Which is precisely what the PMD spec is meant to help against.
  • All basic fields are suitable to CLI tools, as well as GUI applications, or web apps.

    • Additions like icon: etc. can be used for more specific cases.
  • type: is one recommended way to support the more widespread "hook" or service locator systems.

    • Albeit even category: or custom fields can be fitted for more complex needs.
  • Utilizing PMD does not require each and every source script to carry a meta data block.

    • Obviously it's only meant to augment those code bits that represent features or extensions.
    • Though, of course; once you start classifying scripts, or have a huge enough codebase - plugin meta data will appear even in core files. (And I'd usually tag them as such - type: core)
  • "Modules" are not scope of this spec.

    • Of course, for "module packages", one could elect a primary/invocation script, add plugin meta data only there, and leave the rest undocumented.
  • Another essential feature of PMD is a common config: scheme.

    • Many times plugins themselves represent just settings/adaptions.
    • For more complex code it's very common to introduce new global application settings.
    • Rather than leave each plugin to also micromanage an UI for settings those, defining a standard way to collect options (globally or on per-plugin basis) is a neat gimmick.
  • There's quite some overlap. But PMD has an entirely different scope than build/source-packaging tools (npm, pip, composer, etc).

    • The plugin spec is meant for runtime configuration between individual scripts, not a global project recipie.
    • With e.g. depends being more of a recommendation than leading to dependency hell.
    • Its scope is end-user discoverable documetation rather than build systems.
    • Although one could generate/augment e.g. package.json from a list of # depends: npm:xyz, npm:abc, …

Inspired by

Both syntax and usage didn't come out of thin air. There's lots of prior art and things PMD tries to be compatible with to some extend:

  • Standard field names mostly come from the Debian packaging spec. Which is sort of a standard already. (No need for NIH field names.)

  • One of the few things Wordpress got right (almost). They've been using (or rather inherited) a similar comment-based plugin description scheme.

    • Except for the abhorrent spaced key names, and not knowing what else to do with it.
    • Most WP plugins have to define config hooks/settings/handling themselves to this day.
  • There's a few similar language-specific meta data schemes:

    • JS userscripts use a constrained docblock-style scheme for similar purposes.
    • TCL, teapot?
    • ... (readd from old list...)

Why not?

Before PMD came to be, I've also tried a couple of common mishaps:

Meta-data in code:

  • Most intial extensions/plugin schemes (e.g. PHP4-era code) use class constants, properties, or function hooks to register with the application API.

  • However such meta info code is just used in a one-off fashion. Either once for installation, or rarely for option configuration. It still might show up in menus, but otherwise is pretty much dead code.

External .meta/.ini/.xml files

  • For binary apps / compiled languages, having a module description scheme externalized is often unavoidable.

  • But auxilliary meta files often just add complexity (copy and updating them along the real code), not features per se.

  • It's harder to eschew for broader "module" schemes. But for the purpose of slim feature hooks, embeding meta infos turns out most practicable.

DocBlock considered harmful

Most scripting languages use some form of DocBlock, PerlDoc variants, decorators or any custom API documentation scheme. They're quite essential or even existential or function/class-level description.

Not so much for file-level docblocks however. Those decorations rarely add anything worthwhile to autogenerated docs. Which would have been a great reason to repurpose DocBlocks for PMD with an established syntax, but:

  • Most DocBlock parsers trip over custom attributes. A few would just yield a bunch of warnings. But generally there's no support for anything but textual descriptions.

  • The well is poisoned with boilerplate. Due to being this widely adopted, IDEs started adding boilerplate DocBlocks. Which contributed to its diminished usefulness.

  • Variations across languages (PerlDoc vs JavaDoc) also would have made DocBlock look out of place as default syntax for plugin meta data.

Another dealbreaker was the excessive pairing with...

The great license plague of the 90s

License blobs in lieu of proper file-level documentation.

  • Now to be fair, most academic/attribution licenses recommend them to be embeded with source code. (None require this to be at the file start though.)

  • For reciprocal licenses, which do not apply on a file-by-file basis to being with, this is entirely unfounded. Nonetheless it became a toxic habit to plaster source code with license excerpts - oftentimes to avoid effort on actual code descriptions.

  • It's an abomination of the purpose of code comments.

PMD mandates to be in the first comment block in order to combat exactly this. The intend behind the license standard field is to legitimize SPDX identifiers instead.