NAME001: name-pattern
Name does not follow the configured naming convention
| Code | NAME001 |
| Name | name-pattern |
| Category | Naming (NAME) |
| Default severity | warning |
| Enabled by default | no |
| Fix available | sometimes |
| Fix safety | safe or unsafe, depending on the finding (see below) |
| ign-lint equivalent | NamePatternRule |
What it does
Section titled “What it does”Checks the names of components (meta.name), properties (custom
properties, view parameters and the free-form keys inside them), message
handlers (their messageType) and custom methods against a naming
convention or a regular expression, with per-node-type settings. By default
only component names are checked, against PascalCase, and root is skipped.
A failing name gets a suggestion in the configured convention. For
components the suggestion is offered as a fix that renames the component
and updates every reference to it in the view: property references in
every binding and transform field Perspective parses as an expression
({../Label.props.text}, {/root/Panel/Label.custom.x}; the fields are
measured in the Ignition image: expression bindings and structures, query
parameters, tag paths and indirect references, polling rates, tag history
date ranges and return sizes, HTTP URLs, bodies, header and authorization
values, expression and map transforms), property binding paths, and
literal getChild('...') / getSibling('...') calls in scripts whose
receiver resolves (self, self.parent, self.view.rootContainer,
earlier lookups). References are found by resolution, so a different
component with the same name elsewhere in the view is left alone. The
rename is unsafe when a script could find the component another way: it
reads meta.name, or the component's name through the members measured
to return it (self.name, c.getName(), also for a component reached
through children, getChildren(), a loop or an index), looks children
up with a computed name or a matching string, hands a component to code
outside the view, reaches eval, locals() or a frame in any way (also
under another name, __builtin__.eval), calls an unnamed value
(factory()()), or calls a library name that is not a plain function,
class or literal constant (it may be eval under another name; outside a
project any such name counts).
The fix is offered only when every reference can be updated: a literal
lookup on an unresolvable receiver naming the component, a suggestion that
is taken by a sibling or that would itself break the convention, means no
fix. It is safe when nothing could refer to the component in a way
iglint cannot follow: no references at all, no script reads the
component's name (meta.name, name, getName()), no script looks up
children with computed names or has a string literal equal to the name,
every script parses, no script hands a component to code outside the view
(passing self, self.parent, event.source or another component to a
library function, in a message payload, to getGlobals() or to any call
iglint does not model): a library function that receives a component may
call getChild('SaveButton') itself; no string of the view that iglint
does not read as an expression or script holds a {...} reference (an
action's settings, a field of an unknown binding type); no reference is
written with whitespace inside its braces ({ ../Label.props.text },
which Perspective reads as a tag path); no string of the view holds
the name, as a word, anywhere the fix does not update it; and the new name
occurs nowhere in the view: not in any string of the view (a broken
{../NewName.props.text} or binding path ../NewName.props.text would
start to resolve) and not in any string literal of a script
(self.getSibling('NewName'), which finds nothing now, would find the
renamed component), in any spelling that differs only in case.
Perspective compares names exactly, but case variants count too, to stay
on the safe side. Fixed values of Perspective's schema are not searched
for either name: a known component type (ia.input.button), a measured
binding or transform type (query, expr-struct) and the keys leading
to its parsed fields (struct), a known action type and scope, and
the keys of meta other than name. It is unsafe otherwise, and names the place that
keeps it from being safe. The safety net checks the result as well: a
safe fix that changes what any reference of the view resolves to (see
docs/internal/fix-safety.md, "Threat model") is reported as unsafe.
When a character of the name changes length under case mapping (the
ligature fi upper-cases to FI, ß to SS), no suggestion and no fix
are offered and the message says why. Like every
fix, it is also unsafe while code in the workspace may read the files a
fix edits (any file access, read, write, rename or delete, whose path
is not a literal outside the workspace, or
code that is not vetted); the project setting [fix] assume-scripts-do-not-read-workspace-files = true declares that no script
does (see docs/internal/fix-safety.md, "File reads").
Keys of props that the component's schema declares (text, style,
pipes, ...) are Ignition's names, not yours, and are never checked; only
free-form keys (for example the params passed to an embedded view) are.
Style objects, position, private names (starting with _), Java dates
and dataset internals are skipped.
Why is this bad?
Section titled “Why is this bad?”Consistent names make views readable and make references such as
{../SaveButton.props.enabled} predictable. Names with spaces or
punctuation are easy to mistype in property paths and scripts.
Example
Section titled “Example”With convention = "PascalCase":
{"meta": {"name": "save button"}, "type": "ia.input.button"}Use instead:
{"meta": {"name": "SaveButton"}, "type": "ia.input.button"}Options
Section titled “Options”convention(unset by default): one ofPascalCase,camelCase,snake_case,kebab-case,SCREAMING_SNAKE_CASE,Title Case,lower case. Unset means PascalCase without suggestions.custom-pattern(unset by default): a regular expression (matched at the start of the name, like Python'sre.match) that replaces the convention's pattern.suggestion-convention(unset by default): the convention suggestions are written in, when it differs fromconvention(for example with acustom-pattern).target-node-types(unset by default): node types to check:component,property,message_handler,custom_method. Defaults to the keys ofper-type, or["component"].per-type(default{}): a table from node type to overrides ofconvention,pattern,pattern_description,suggestion_convention,min_length,max_length,forbidden_names,skip_names,severityandallow_numbers.allow-numbers(defaulttrue): whether convention patterns accept digits.min-length(default1),max-length(unset by default): length limits (characters).forbidden-names(default[]): names that are always reported.skip-names(default["root"]): names never checked; giving a list replaces the default["root"].allowed-abbreviations(default[]): extra abbreviations; an abbreviation written in capitals as a whole word is accepted where the convention writes words differently (read_API_datain snake_case,API Keyin Title Case). In camelCase one of these is also accepted as the whole name or the first word (ID,IMLocationwith["ID", "IM"]); the built-in list ofauto-detect-abbreviationsis not, soHTTPServeris still reported.auto-detect-abbreviations(defaulttrue): also use the built-in list (API,HTTP,ID,URL, ...).
ign-lint
Section titled “ign-lint”Equivalent of NamePatternRule; every kwarg maps to the option of the same
name (node_type_specific_rules is per-type) and iglint ign-lint
prints the same messages. Intended differences
(docs/compat/ign-lint-differences.md): abbreviations only ever widen what
is accepted (ign-lint's substring replacement rejects idleTimer,
restartButton or urlParams in camelCase and accepts any SCREAMING name
containing an abbreviation); suggestions keep digits and split words
consistently (badEmbeddedPotato_0 becomes BadEmbeddedPotato0, not
Badembeddedpotato0); a component is never reported as colliding with its
own name; schema-defined props keys and propConfig metadata are not
properties; object-valued properties are checked too, not only leaves;
renames update references by resolution and are unsafe when scripts could
refer to the component dynamically.
Option reference
Section titled “Option reference”Set in [rules.NAME001] of iglint.toml (or [tool.iglint.rules.NAME001] in pyproject.toml).
| Option | Type | Default | Description |
|---|---|---|---|
convention |
string | none | Naming convention of all node types. |
custom-pattern |
string | none | Regular expression replacing the convention's pattern. |
suggestion-convention |
string | none | Convention used for suggestions. |
target-node-types |
array of strings | none | Node types to check. |
per-type |
table | {} |
Per node type overrides. |
allow-numbers |
boolean | true |
Whether convention patterns accept digits. |
min-length |
integer | 1 |
Minimum name length. |
max-length |
integer | none | Maximum name length. |
forbidden-names |
array of strings | [] |
Names that are always reported. |
skip-names |
array of strings | ["root"] |
Names never checked. |
allowed-abbreviations |
array of strings | [] |
Extra abbreviations. |
auto-detect-abbreviations |
boolean | true |
Use the built-in abbreviation list. |
ign-lint kwargs in a rule_config.json: convention -> convention, custom_pattern -> custom-pattern, suggestion_convention -> suggestion-convention, target_node_types -> target-node-types, node_type_specific_rules -> per-type, allow_numbers -> allow-numbers, min_length -> min-length, max_length -> max-length, forbidden_names -> forbidden-names, skip_names -> skip-names, allowed_abbreviations -> allowed-abbreviations, auto_detect_abbreviations -> auto-detect-abbreviations.
Generated from the rule metadata by iglint generate-docs; iglint rule NAME001 prints the same page in the terminal. Source: docs/rules/NAME001.md.