File: MANIFEST-FORMAT.md.j2

package info (click to toggle)
debputy 0.1.81
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,748 kB
  • sloc: python: 66,966; sh: 164; perl: 155; makefile: 43; ansic: 5
file content (561 lines) | stat: -rw-r--r-- 25,554 bytes parent folder | download | duplicates (2)
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
<#

    This is the template file. For the generated output; provide the "this is auto-generated" marker

    Want to improve some docs from the generated file that is not in this template? Have a look
    in:
      * src/debputy/plugins/debputy
      * src/debputy/plugin/api/std_docs.py.

    Most of the online documentation comes from those places.

#>
<!--
  THIS FILE IS AUTO-GENERATED; Please edit MANIFEST-FORMAT.md.j2 instead or the `debputy` command
  generating this out.

  REGENERATE WITH:

    debputy internal-command process-template docs/MANIFEST-FORMAT.md.j2 MANIFEST-FORMAT.md

-->

# The debputy manifest format

_This is [reference documentation] and is primarily useful if you have an idea of what you are looking for._
_If you are new to `debputy`, maybe you want to read [GETTING-STARTED-WITH-dh-debputy.md](GETTING-STARTED-WITH-dh-debputy.md) first._

<!-- To writers and reviewers: Check the documentation against https://documentation.divio.com/ -->

<#

## Template form

This file is a python3-jinja2 template file (https://jinja.palletsprojects.com/en/stable/templates/).
This section serves as instructions for how the template works, but it will **not** be included in
the generated form courtesy of the surrounding markers.

The jinja template is triggered by using `<` rather than `{` and `>` for `}`. So `<<foo>>` is a template
variable rather than the default of `{{foo}}`. This is to avoid problems with the `debputy` example
syntax, where `{{FOO}}` is a `debputy` substitution variable.

Relevant features:

  * <<render_pmr("foo::bar", heading_level)>> will render the docs a la `debputy plugin show p-m-r foo::bar`.
  * <<render_tm("Foo", heading_level)>> will render the docs a la `debputy plugin show type-mappings Foo`.
  * <<render_all_tms(heading_level)>> will render the docs for all non-simple type mappings. Basically, a loop
    over all type mappings (a la: `debputy plugin list type-mappings`) followed by rendering each type mapping
    (<<render_tm(NAME, heading_level)>>). The heading_level will be passed to <<render_tm(...)>>.

For `heading_level`, use the header level desired (`1` for `#` or `<h1>`, `2` for `##` or `<h2>`, etc.).

#>
## Prerequisites

This guide assumes familiarity with Debian packaging in general.  Notably, you should understand
the different between a (Debian) source package and a (Debian) binary package (e.g., `.deb`) plus
how these concepts relates to `debian/control` (the source control file).

Additionally, the reader is expected to have an understanding of globs and substitution variables.

It is probably very useful to have an understanding on how a binary package is
assembled.  While `debputy` handles the assembly for you, this document will not go in details
with this. Prior experience with `debhelper` (notably the `dh`-style `debian/rules`) may be
useful but should not be a strict requirement.


# The basic manifest

The manifest is a YAML document with a dictionary at the top level layer.  As usual with YAML
versions, you can choose to leave it implicit.  All manifests must include a manifest version, which
will enable the format to change over time.  For now, there is only one version (`0.1`) and you have
to include the line:

    manifest-version: "0.1"


On its own, the manifest containing only `manifest-version: "..."` will not do anything.  So if you
end up only having the `manifest-version` key in the manifest, you can just remove the manifest and
rely entirely on the built-in rules.

## Feature limitations due to Integration Mode

The `debputy` program is build around different integration modes as documented
[INTEGRATION-MODES.md](INTEGRATION-MODES.md). Certain features require a certain integration
mode to work, which the documentation mention where relevant.

# Path matching rules

Most of the manifest is about declaring rules for a given path such as "foo must be a symlink"
or "bar must be owned by root:tty and have mode 02755".

The manifest contains the following types of matches:

 1) Exact path matches.  These specify the path inside the Debian package exactly without any
    form of wildcards (e.g., `*` or `?`).  However, they can use substitution variables.
    Examples include:
    * `usr/bin/sudo`
    * `usr/lib/{{DEB_HOST_MULTIARCH}}/libfoo.so`

    Having a leading `/` is optional.  I.e. `/usr/bin/sudo` and `usr/bin/sudo` are considered the
    same path.

 2) Glob based path matches.  These specify a rule that match any path that matches a given
    glob.  These rules must contain a glob character (e.g., `*`) _and_ a `/`. Examples include:

    * `foo/*`
    * `foo/*.txt`
    * `usr/lib/{{DEB_HOST_MULTIARCH}}/lib*.so*`

    Note that if the glob does not contain a `/`, then it falls into the Basename glob rule
    below.

 3) Basename glob matches.  These specify a rule that match any path where the basename matches
    a given glob.  They must contain a glob character (e.g., `*`) but either must not have a
    `/` in them at all or start with `**/` and not have any `/` from there.
    Examples include:

    * `"*.la"`
    * `"**/*.md"`
    * `"**/LICENSE"`

    The examples use explicit quoting because YAML often interprets `*` as an anchor rule in the
    places where you are likely to use this kind of glob.  The use of the `**/`-prefix is
    optional when the basename is a glob.  If you wanted to match all paths with the basename
    of exactly `LICENSE`, then you have to use the prefix (that is, use `**/LICENSE`) as `LICENSE`
    would be interpreted as an exact match for a top-level path.

However, there are also cases where these matching rules can cause conflicts.  This is covered
in the [Conflict resolution](#conflict-resolution) section below.


## Limitations on debputy path rules

Path rules:

 1) Must match relatively to the package root.
 2) Never resolves a symlink.
    * If `bin/ls` is a symlink, then `bin/ls` matches the symlink (and never the target)
    * If `bin` is a symlink, then `bin/ls` (or `bin/*`) would fail to match, because
      matching would require resolving the symlink.

These limitations are in place because of implementation details in `debputy`.


## Conflict resolution

The manifest can contain seemly mutually exclusive rules.  As an example, if you ask for
`foo/symlink` to be a symlink but also state that you want to remove `foo` entirely
from the Debian package then the manifest now has two mutually exclusive requests.

To resolve these problems, `debputy` generally relies on ordered instructions to
resolve conflicts. Consider `installations` and `transformations`:

   1. `installations` (ordered list using "first match wins")
   2. `package.<package-name>.transformations` (ordered list using "all matching rules applies")

The "first match wins" rule means the first rule that applies will be used for that match
and no further rules will be used for that match.

The "all matching rules applies" rule means that each rule is applied in order.  Often
this behaves like a simple case of either "first match wins" or "last match wins" (depending
on the context).

Note for transformation rules, an early rule can change the file system layout, which will
affect whether a later rule matches.  This is similar to how shell globs commands work:

      $ rm usr/lib/libfoo.la
      $ chmod 0644 usr/lib/*

Here the glob used with `chmod` will not match `usr/lib/libfoo.la` because it was removed.
As noted, a similar logic applies to transformation rules.

## All definitions must be used

Whenever you define a request or rule in the manifest, `debputy` will insist on it being used
at least once.  The exception to this rule being conditional rules where the condition
evaluates to `false` in which case the rule does not trigger an error when unused.

This is useful for several reasons:

 1. The definition may have been shadowed by another rule and would have been ignored otherwise
 2. The definition may no longer be useful, but its present might confuse a future reader of
    the manifest.

In all cases, `debputy` will tell you if a definition was unused and where you can find that
definition.

## debputy globs

In general, the following rules applies to globs in `debputy`.

 * The `*` match 0 or more times any characters except `/`.
 * The `?` match exactly one character except `/`.
 * The glob `foo/*` matches _everything_ inside `foo/` including hidden files (i.e., paths starting
   with `.`) unlike `bash`/`sh` globs. However, `foo/*` does _not_ match `foo/` itself (this latter
   part matches `bash`/`sh` behavior and should be unsurprising).
 * For the special-cases where `**` is supported, then `**` matches zero or more levels of directories.
   This means that `foo/**/*` match any path beneath `foo` (but still not `foo`).  This is mostly relevant
   for built-in path matches as it is currently not possible to define `foo/**/...` patterns in the manifest.

Note that individual rules (such as `clean-after-removal`) may impose special cases to how globs
work. The rules will explicitly list if they divert from the above listed glob rules.

# Rules for substituting manifest variables

The `debputy` tool supports substitution in various places (usually paths) via the following
rules.  That means:

 1) All substitutions must start with `{{` and end with `}}`.  The part between is
    the `MANIFEST_VARIABLE` and must match the regular expression `[A-Za-z0-9][-_:0-9A-Za-z]*`.
    Note that you can use space around the variable name if you feel that increases readability.
    (That is, `{{ FOO }}` can be used as an alternative to `{{FOO}}`).
 2) The `MANIFEST_VARIABLE` will be result from a set of built-in variables and the variables from
    `dpkg-architecture`.
 3) You can use `{{token:DOUBLE_OPEN_CURLY_BRACE}}` and `{{token:DOUBLE_CLOSE_CURLY_BRACE}}` (built-in
    variables)  if you want a literal `{{` or `}}`  would otherwise have triggered an undesired expansion.
 4) All `{{MANIFEST_VARIABLE}}` must refer to a defined variable.
    - You can see the full list of `debputy` and plugin provided manifest variables via:
      `debputy plugin list manifest-variables`. The manifest itself can declare its own variables
      beyond that list. Please refer to the [Manifest Variables](#manifest-variables-variables)
      section manifest variables declared inside the manifest.
 5) There are no expression syntax inside the `{{ ... }}` (unlike jinja2 and other template languages).
    This rule may be changed in the future (with a new manifest version).

Keep in mind that substitution _cannot_ be used everywhere.  There are specific places where
it can be used.  Also, substitution _cannot be used_ to introduce globs into paths.  When a
substitution occurs inside a path all characters inserted are treated as literal characters.

Note: While manifest variables can be substituted into various places in the `debputy` manifest, they
are distinct from `dpkg`'s "substvars" (`man 5 deb-substvars`) that are used in the `debian/control`
file.

## Built-in or common substitution variables

 * `{{token:NEWLINE}}` or `{{token:NL}}` expands to a literal newline (LF) `\n`.
 * `{{token:TAB}}` expands to a literal tab `\t`.
 * `{{token:OPEN_CURLY_BRACE}}`  / `{{token:CLOSE_CURLY_BRACE}}` expand to `{` / `}`
 * `{{token:DOUBLE_OPEN_CURLY_BRACE}}` / `{{token:DOUBLE_CLOSE_CURLY_BRACE}}` expands to `{{` / `}}`.
 * `{{PACKAGE}}` expands to the binary package name of the current binary package. This substitution
   only works/applies when the substitution occurs in the context of a concrete binary package.
 * Plus any of the variables produced by `dpkg-architecture`, such as `{{DEB_HOST_MULTIARCH}}`.

The following variables from `/usr/share/dpkg/pkg-info.mk` (`dpkg`) are also available:

 * DEB_SOURCE (as `{{DEB_SOURCE}}`)
 * DEB_VERSION (as `{{DEB_VERSION}}`)
 * DEB_VERSION_EPOCH_UPSTREAM (as `{{DEB_VERSION_EPOCH_UPSTREAM}}`)
 * DEB_VERSION_UPSTREAM_REVISION (as `{{DEB_VERSION_UPSTREAM_REVISION}}`)
 * DEB_VERSION_UPSTREAM (as `{{DEB_VERSION_UPSTREAM}}`)
 * SOURCE_DATE_EPOCH (as `{{SOURCE_DATE_EPOCH}}`)

These have the same definition as those from the `dpkg` provided makefile.


# Restrictions on defining ownership of paths

In some parts of the manifest, you can specify which user or group should have ownership of
a given path.  As an example, you can define a directory to be owned by `root` with group `tty`
(think `chown root:tty <some/path>`).

Ownership is generally defined via the keys `owner` and `group`.  For each of them, you can use
one of the following formats:

 1) A name (e.g., `owner: root`).
 2) An id (e.g., `owner: 0`). Please avoid using quotes around the ID in YAML as that can
    cause `debputy` to read the number as a name.
 3) A name and an id with a colon in between (e.g., `owner: "root:0"`).  The name must always
    come first here.  You may have to quote the value to prevent the YAML parser from being
    confused.

All three forms are valid and provide the same result.  Unless you have a compelling reason to
pick a particular form, the name-only is recommended for simplicity.  Notably, it does not
require your co-maintainer or future you to remember what the IDs mean.

Regardless of which form you pick:

 1) The provided owner must be defined by Debian `base-passwd` file, which are the only users guaranteed
    to be present on every Debian system.
    * Concretely, `debputy` verifies the input against `/usr/share/base-passwd/passwd.master` and
      `/usr/share/base-passwd/group.master` (except for `root` / `0` as an optimization).

 2) If the `name:id` form is used, then the name and the id values must match.  I.e., `root:2` would
    be invalid as the id for `root` is defined to be `0` in the `base-passwd` data files.

 3) The `debputy` tool maintains a `deny`-list of owners that it refuses even though `base-passwd`
    defines them. As a notable non-exhaustive example, `debputy` considers `nobody` or id `65534`
    (the ID of `nobody` / `nogroup`) to be invalid owners.


# Conditional rules

There are cases, where a given rule should only apply in certain cases - such as only when a given
build profile is active (`DEB_BUILD_PROFILES` / `dpkg-buildpackage -P`).  For rules that
*support being conditional*, the condition is generally defined via the `when:` key and the condition
is then described beneath the `when:`.

As an example:

    packages:
        util-linux:
            transformations:
            - create-symlink
                  path: sbin/agetty
                  target: /sbin/getty
                  when:
                      # On Hurd, the package "hurd" ships "sbin/getty".
                      arch-matches: '!hurd-any'


When the condition under `when:` resolves to `true`, the rule will and must be used.  When the
condition resolves to `false`, the rule will not be applied even if it could have been.  However,
the rule may still be "partially" evaluated.  As an example, for installation rules, the source
patterns will still be evaluated to reserve what it would have matched, so that following rules
behave deterministically regardless of how the condition evaluates.

Note that conditions are *not* used as a conflict resolution and as such two conditional rules
can still cause conflicts even though their conditions are mutually exclusive.  This may be
changed in a later version of `debputy` provided `debputy` can assert the two conditions
are mutually exclusive.

The `when:` key has either a mapping, a list or a string as value depending on the condition.
Each supported condition is described in the following subsections.


<<render_pmr('ManifestCondition::arch-matches', 2)>>
<#- source-context-arch-matches and package-context-arch-matches share docs, so we only need one of them -#>
<<render_pmr('ManifestCondition::source-context-arch-matches', 2)>>
<<render_pmr('ManifestCondition::build-profiles-matches', 2)>>
<<render_pmr('ManifestCondition::can-execute-compiled-binaries', 2)>>
<<render_pmr('ManifestCondition::cross-compiling', 2)>>
<<render_pmr('ManifestCondition::run-build-time-tests', 2)>>
<<render_pmr('ManifestCondition::not', 2)>>
<# all-of and any-of share docs, so we only need one of them -#>
<<render_pmr('ManifestCondition::all-of', 2)>>

# Packager provided definitions

For more complex manifests or packages, it is possible define some common attributes for reuse.

<<render_pmr('definitions::variables', 2)>>

# Interacting with upstream build system

In the `full` integration mode, `debputy` also attempts to interact with the upstream build
systems (if any). In other integration modes, then it is generally `dh` that manages the
upstream build system (via the `dh_auto_*` commands). By default, `debputy` in the `full`
integration mode will auto-detect a supported build system and apply some defaults for a
build. However, in some cases, you may need to tweak some settings, which will covered
with these rules.

<<render_pmr('::default-build-environment', 2)>>
<<render_pmr('::build-environments', 2)>>
<<render_pmr('::builds', 2)>>

<<render_pmr('BuildRule::autoconf', 3)>>
<<render_pmr('BuildRule::make', 3)>>
<<render_pmr('BuildRule::perl-build', 3)>>
<<render_pmr('BuildRule::perl-makemaker', 3)>>
<<render_pmr('BuildRule::debhelper', 3)>>
<<render_pmr('BuildRule::cmake', 3)>>
<<render_pmr('BuildRule::meson', 3)>>
<<render_pmr('BuildRule::qmake', 3)>>
<<render_pmr('BuildRule::qmake6', 3)>>

## Test rules (`builds.*.test-rule`)

Build systems can be associated with a `test-rule`, which adds a maintainer restriction running
the build time test suite.

<<render_pmr('TestRule::skip-tests', 3)>>
<<render_pmr('TestRule::skip-tests-when', 3)>>

<<render_pmr('::installations', 1)>>

## Install rule search directories

Most install rules apply their patterns against search directories such as `debian/tmp` by default.

The default search directory order (highest priority first) is:

 1) The upstream install directory (usually, `debian/tmp`)
 2) The source package root directory (`.`)

Each search directory is tried in order.  When a pattern matches an entry in a search directory (even
if that entry is reserved by another package), further search directories will *not* be tried. As an example,
consider the pattern `usr/bin/foo*` and the files:

  `SOURCE_ROOT/debian/tmp/usr/bin/foo.sh`
  `SOURCE_ROOT/usr/bin/foo.pl`

Here the pattern will only match `SOURCE_ROOT/debian/tmp/usr/bin/foo.sh` and not `SOURCE_ROOT/usr/bin/foo.pl`.

## Automatic discard rules

The `debputy` framework provides some built-in discard rules that are applied by default during installation
time.  These are always active and implicit, but can be overwritten by exact path matches for install rules.

The `debputy` tool itself provides the following discard rules:

 * Discard of `.la` files. Their use is rare but not unheard of. You may need to overwrite this.
 * Discard of python byte code (such as `__pycache__` directories).
 * Discard of editor backup files (such as `*~`, `*.bak`, etc.).
 * Discard of Version control files (such as `.gitignore`, etc.).
 * Discard of GNU info's `dir` (`usr/share/info/dir`) as it causes file conflicts with other packages.
 * Discard of `DEBIAN` directory.

Note: Third-party plugins may provide additional automatic discard rules. Please use
`debputy plugin list automatic-discard-rules` to see all known automatic discard rules.

If you find yourself needing a particular path installed that has been discarded by default, you can overrule
the default discard by spelling out the path. As an example, if you needed to install a `libfoo.la` file,
you could do:

    installations:
      - install:
            sources:
            # By-pass automatic discard of `libfoo.la` - globs *cannot* be used!
             - "usr/lib/libfoo.la"
             - "usr/lib/libfoo*.so*"
            into: libfoo1

<<render_pmr('InstallRule::install', 2)>>
<<render_pmr('InstallRule::install-docs', 2)>>
<<render_pmr('InstallRule::install-examples', 2)>>
<<render_pmr('InstallRule::install-man', 2)>>
<<render_pmr('InstallRule::discard', 2)>>
<<render_pmr('InstallRule::multi-dest-install', 2)>>

# Binary package rules

Inside the manifest, the `packages` mapping can be used to define requests for the binary packages
you want `debputy` to produce.  Each key inside `packages` must be the name of a binary package
defined in `debian/control`.  The value is a dictionary defining which features that `debputy`
should apply to that binary package.  An example could be:


    packages:
        foo:
            transformations:
                - create-symlink:
                      path: usr/share/foo/my-first-symlink
                      target: /usr/share/bar/symlink-target
                - create-symlink:
                      path: usr/lib/{{DEB_HOST_MULTIARCH}}/my-second-symlink
                      target: /usr/lib/{{DEB_HOST_MULTIARCH}}/baz/symlink-target
        bar:
            transformations:
            - create-directories:
               - some/empty/directory.d
               - another/empty/integration-point.d
            - create-directories:
                 path: a/third-empty/directory.d
                 owner: www-data
                 group: www-data

In this case, `debputy` will create some symlinks inside the `foo` package and some directories for
the `bar` package.  The following subsections define the keys you can use under each binary package.


<<render_pmr('::transformations', 2)>>
<<render_pmr('TransformationRule::remove', 3)>>
<<render_pmr('TransformationRule::move', 3)>>
<<render_pmr('TransformationRule::create-symlink', 3)>>
<<render_pmr('TransformationRule::create-directories', 3)>>
<<render_pmr('TransformationRule::path-metadata', 3)>>

<<render_pmr('packages.{{PACKAGE}}::services', 2)>>

### Service managers and aliases

When defining a service rule, you can use any name that any of the relevant service managers would call the
service. As an example, consider a package that has the following services:

 * A `sysvinit` service called `foo`
 * A `systemd` service called `bar.service` with `Alias=foo.service` in its definition.

Here, depending on which service managers are relevant to the rule, you can use different names to match.
When the rule applies to the `systemd` service manager, then either of the following names can be used:

 * `bar.service` (the "canonical" name in the systemd world)
 * `foo.service` (the defined alias)
 * `bar` + `foo` (automatic aliases based on the above)

Now, if rule *also* applies to the `sysvinit` service manager, then any of those 4 names would cause the
rule to apply to both the `systemd` and the `sysvinit` services.

To show concrete examples:

    ...:
            services:
              # Only applies to systemd. Either of the 4 names would have work.
              - service: "foo.service"
                on-upgrade: stop-then-start
                service-manager: systemd

    ...:
            services:
              # Only applies to sysvinit. Must use `foo` since the 3 other names only applies when systemd
              # is involved.
              - service: "foo"
                on-upgrade: stop-then-start
                service-manager: sysvinit

    ...:
            services:
              # Applies to both systemd and sysvinit; this works because the `systemd` service provides an
              # alias for `foo`. If the systemd service did not have that alias, only the `systemd` service
              # would have been matched.
              - service: bar
                enable-on-install: false

<<render_pmr('packages.{{PACKAGE}}::binary-version', 2)>>
<<render_pmr('packages.{{PACKAGE}}::clean-after-removal', 2)>>
<<render_pmr('packages.{{PACKAGE}}::installation-search-dirs', 2)>>
<<render_pmr('packages.{{PACKAGE}}::built-using', 2)>>
<<render_pmr('packages.{{PACKAGE}}::static-built-using', 2)>>

<<render_pmr('::remove-during-clean', 1)>>

# Type listing

During the documentation, you may see references to a types such as `ManifestCondition` or `TestRule`.

The documentation for these are:

 * [`ManifestCondition`](#conditional-rules)
 * [`BuildRule`](#build-rules-builds) or [`BuildSystemRule`](#build-rules-builds)
 * [`TestRule`](#test-rules-buildstest-rule)
 * [`InstallRule`](#installations-installations)
 * [`TransformationRule`](#transformations-transformations)

Additionally, there are some type mappings such as `OctalMode`. These are documented below.

## Base types

These are the base types, which you may see.

 * `string`: A simple string. Often accepts substitutions in form of `{{VARIABLE}}`.
 * `int`: An integer.
 * `list of X`: A list of `X`, where `X` is a separate type.
 * `mapping of X`: A mapping. The keys are always `string` and the values are of type `X`,
   where `X` is a separate type.

## Type mappings

Here are some named types used in the documentation.

<<render_all_tms(3)>>

## Other type mappings

If you see a type that is not listed anywhere in this document, then it might be from a third-party
plugin. Try one of the following commands to resolve it:

 * `debputy plugin show type-mappings <TypeMapping>`
 * `debputy plugin show p-m-r <attribute-name>` (or `debputy plugin show p-m-r <BaseType>::<attribute-name>`)

You can also do this with `debputy` provided types. As an example `debputy plugin show type-mappings OctalMode`
or `debputy plugin show p-m-r install-man` (a.k.a. `debputy plugin show p-m-r InstallRule::install-man`).

[reference documentation]: https://documentation.divio.com/reference/