Linter

Blueprint files can be linted with the Blueprint Compiler. For a single file to be linted use:

python blueprint-compiler.py lint <file1.blp>

For checking multiple files, just add them to the above command like this:

python blueprint-compiler.py lint <file1.blp> <file2.blp> <file3.blp>

An entire dirctory can also be scanned by specifiying the folder location:

python blueprint-compiler.py lint test/directory/location/

Contexts

The linter is intended to flag issues related to accessibility, best practices, and logical errors. The development of the linter is still ongoing so new rules and features are being added in the future.

Following are some examples of the linter rules that have been implemented so far.

Accessibility Rules

Missing user-facing text properties

Rule: missing_user_facing_properties Details: Properties are required for each element declared. For example components such as Label:label, Entry:placeholder should use appropriate human readable text, and follow typography from GNOME HIG.

Examples of incorrect code for this rule:

Button {
}
Entry {
}

Examples of correct code for this rule:

Button {
   label: _("Submit");
}
Entry {
   placeholder-text: _("Enter username");
}

Avoid all caps

Rule: avoid_all_caps Details: The use of caps should be avoided in user facing texts.

Examples of incorrect code for this rule:

Button {
  label: _("SUBMIT");
}

Examples of correct code for this rule:

Button {
  label: _("Submit");
}

Warn against ASCII characters

Rule: prefer_unicode_chars Details: Unicode is preferred over ASCII characters whenever possible.

Examples of incorrect code for this rule:

// Using ASCII characters
Label {
   label: _("Click "OK"");
}

Examples of correct code for this rule:

// Using Unicode
Label {
   label: _("Click “OK”");
}

Logical Rules

No child or single child allowed

Rule: number_of_children Details: Passing children to objects that don’t accept any, such as Label, will not provide any feedback. It is confusing for beginners as the children don’t get rendered but no explanation is given. In addition some widgets like AdwStatusPage, Adw.Clamp, ScrolledWindow etc. allow only one child. Only the last child will be rendered.

Examples of incorrect code for this rule:

// No child allowed
Label {
   label: "Hello";
      Button {
         label: "World";
      }
}

// Single child allowed
Adw.StatusPage {
   Button {
      label: "a";
   }

   Button {
      label: "b";
   }
}

Examples of correct code for this rule:

// No child allowed
Label {
   label: "Hello";
}

// Single child allowed
Adw.StatusPage {
   Button {
      label: "a";
   }
}

Order of properties on Gtk.Adjustment

Rule: order_properties_gtk_adjustment Details: Warn if Gtk.Adjustment properties are declared out of order (lower, upper, and then value).

Examples of incorrect code for this rule:

Scale one {
   width-request: 130;
   adjustment: Adjustment {
      lower: 0;
      value: 50;
      upper: 100;
   };
}

Examples of correct code for this rule:

Scale one {
   width-request: 130;
   adjustment: Adjustment {
      lower: 0;
      upper: 100;
      value: 50;
   };
}

Miscellaneous Rules

Wrap user visible strings with _(…)

Rule: translatable_display_string Details: User visible strings should be marked as translatable using _(…)

Examples of incorrect code for this rule:

Label {
   label: "foo";
}
Button {
   tooltip-text: "foo";
}
Window {
   title: "foobar";
}

Examples of correct code for this rule:

Label {
   label: _("foo");
}
Button {
   tooltip-text: _("foo");
}
Window {
   title: _("foobar");
}

Discourage css-classes usage

Rule: use_styles_over_css_classes Details: Promotes the use of styles array instead of css-classes which overrides default classes.

Examples of incorrect code for this rule:

Box {
   orientation: vertical;
   overflow: hidden;
   css-classes: ["shadowed"];
}

Examples of correct code for this rule:

Box {
   orientation: vertical;
   overflow: hidden;
   styles [
      "Card",
      "translation-side-box",
   ]
}

Warn on incorrect widget placement

Rule: incorrect_widget_placement Details: A widget is declared but not used under an appropriate parent widget.

Examples of incorrect code for this rule:

// If this widget is declared but never added to a container (Box, Window, etc.). It's invisible and unused.

Label {
   label: _("Info")
}

Examples of correct code for this rule:

// Label is part of a Box and Window which is rendered on a screen.

@template Window
window ApplicationWindow {
   default-width: 300
   default-height: 100
   title: _("Used widget")

   Box {
      orientation: vertical
      spacing: 6

      Label {
         label: _("Info")
      }
   }
}

Clamp in ScrolledWindow warning

Rule: clamp_scrolledwindow Details: Clamp should be used as a child property to ScrolledWindow for proper scroll behavior.

Examples of incorrect code for this rule:

ScrolledWindow {
   child: Adw.Clamp {
      child: Box {
         Label {
         label: _("This is incorrect");
         }
      }
   }

Examples of correct code for this rule:

Adw.Clamp {
   child: ScrolledWindow {
      child: Box {
         Label {
         label: _("This is correct");
         }
      }
   }
}