VIEW013: property-persistence
Bound custom property persistence differs from the project convention
| Code | VIEW013 |
| Name | property-persistence |
| Category | View structure (VIEW) |
| Default severity | warning |
| Enabled by default | no |
| Fix available | sometimes |
| Fix safety | safe or unsafe, depending on the finding (see below) |
| ign-lint equivalent | PropertyPersistenceRule |
What it does
Section titled “What it does”Checks persistent on the propConfig entries of bound custom properties
(custom.* entries with a binding, view level and components) against
expected-persistent. A missing persistent means persistent. Nothing is
checked until expected-persistent is set.
expected-persistent = false: reports bound properties that are persistent. The Designer then writes every binding result intoview.json, which bloats the file and produces noisy diffs.expected-persistent = true: reports bound properties that are not persistent, and persistent ones without a stored default value.
Why is this bad?
Section titled “Why is this bad?”A bound, persistent property stores the Designer's last binding result in the resource. Query results and tag values end up in version control and change on every save.
Example
Section titled “Example”With expected-persistent = false:
{"custom": {"rows": [1, 2, 3]}, "propConfig": {"custom.rows": {"binding": {"type": "query", "config": {"queryPath": "Rows"}}}}}Use instead:
{"custom": {}, "propConfig": {"custom.rows": {"binding": {"type": "query", "config": {"queryPath": "Rows"}}, "persistent": false}}}Options
Section titled “Options”expected-persistent(unset by default):trueorfalse; unset disables the rule.exempt-binding-types(default["tag"]): binding types that are not checked:expr,expr-struct,property,query,tag(every tag mode),tag.direct,tag.indirect,tag.expression, and the other registered types (tag-history,http). Default["tag"];[]checks everything.
For expected-persistent = false: sets persistent: false and removes
the stored value (when its path has no array index). Safe when there is
no stored value (the property starts out absent either way). Unsafe when
there is one: until the binding delivers its first value (query bindings
are asynchronous), startup scripts, change scripts and expressions see
the stored value before the fix and no value after it.
Like every fix, it is 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").
ign-lint
Section titled “ign-lint”Equivalent of PropertyPersistenceRule (expected_persistent,
exempt_binding_types), with the same messages in iglint ign-lint.
Option reference
Section titled “Option reference”Set in [rules.VIEW013] of iglint.toml (or [tool.iglint.rules.VIEW013] in pyproject.toml).
| Option | Type | Default | Description |
|---|---|---|---|
expected-persistent |
boolean | none | Whether bound custom properties must be persistent. |
exempt-binding-types |
array of strings | ["tag"] |
Binding types that are not checked. |
ign-lint kwargs in a rule_config.json: expected_persistent -> expected-persistent, exempt_binding_types -> exempt-binding-types.
Generated from the rule metadata by iglint generate-docs; iglint rule VIEW013 prints the same page in the terminal. Source: docs/rules/VIEW013.md.