Skip to content

Commit

Permalink
Add unavailable_system_classes rule (lyft#34)
Browse files Browse the repository at this point in the history
This adds the `unavailable_system_classes` rule. This ensures that a given tag (i.e. `<button>`, `<viewController>`, etc.) has one of the specified custom classes.

With the following configuration:

```json
{
  "rules": [
    "unavailable_system_classes"
  ],
  "rules_config": {
    "unavailable_system_classes": {
      "system_classes": {
        "navigationController": ["CoreUI.NavigationController"]
      }
    }
}
```

This has the following redacted output on the Lyft project:

```
Car.storyboard:248: error: E8E-bb-ZGv: `<navigationController>` must use `CoreUI.NavigationController` instead of `LyftUI.NavigationController`. [rule: strict_customization]
Map.storyboard:658: error: TXt-Ri-g2P: `<navigationController>` must use `CoreUI.NavigationController` instead of `LyftUI.NavigationController`. [rule: strict_customization]
Passenger.storyboard:372: error: 9wW-6l-rv8: `<navigationController>` without a custom class is prohibited. Use `CoreUI.NavigationController` instead. [rule: strict_customization]
Driver.storyboard:1336: error: Zpe-RA-erm: `<navigationController>` must use `CoreUI.NavigationController` instead of `LyftUI.NavigationController`. [rule: strict_customization]
```
  • Loading branch information
soffes authored and keith committed Nov 27, 2018
1 parent a2c621a commit ad57647
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ in the .xib or .storyboard file.

Prevent a list of classes from appearing as custom classes. Configure `custom_classes` in a custom rule configuration using `rules_config` (see below). This is a mapping of the full name of the class (`ModuleName.ClassName`) to the suggested replacement.

- `unavailable_system_classes`

Ensures a system type uses a set of custom clases. Configure `system_classes` in a custom rule configuration using `rules_config` (see below).

## Usage

For a list of available rules, run `xiblint -h`.
Expand Down
41 changes: 41 additions & 0 deletions xiblint/rules/unavailable_system_classes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from xiblint.rules import Rule


class UnavailableSystemClasses(Rule):
"""
Ensures given system types are subclassed by a set of classes.
You must specify a module as part of the class name.
Example configuration:
{
"system_classes": {
"navigationController": ["ModuleName.CustomNavigationController"],
"button": ["ModuleName.CoolButton", "ModuleName.CoolerButton"]
}
}
"""
def check(self, context): # type: (Rule, xiblint.xibcontext.XibContext) -> None
custom_classes = self.config.get('system_classes', {})

for tag_name in custom_classes.keys():
for element in context.tree.findall('.//{}'.format(tag_name)):
tag_name = element.tag
options = custom_classes.get(tag_name)
custom_class = element.get('customClass')
options_string = '`, `'.join(options)

if not custom_class:
context.error(element, '`<{}>` without a custom class is prohibited. Use `{}` instead.'
.format(tag_name, options_string))
continue

full_class_name = self._full_class_name(element)
if full_class_name in custom_classes:
continue

context.error(element, '`<{}>` must use `{}` instead of `{}`.'
.format(tag_name, options_string, full_class_name))

def _full_class_name(self, element): # type: (Rule, Element) -> str
return "{}.{}".format(element.get('customModule'), element.get('customClass'))

0 comments on commit ad57647

Please sign in to comment.