| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
| +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
| ## 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:](wiki/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.
## 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](wiki/license) standard field is to legitimize SPDX identifiers
instead.
|