Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
from xiblint.rules import Rule
from xiblint.xibcontext import XibContext
import glob
import json
class ColorAssets(Rule):
def __init__(self, config):
asset_catalog_path = config.get("asset_catalog", None)
if asset_catalog_path is None:
raise SystemExit(
"error: Asset catalog not found. Please configure 'asset_catalog'.",
)
self.assets = glob.glob("{}/**/*.colorset".format(asset_catalog_path))
if not self.assets:
raise SystemExit(
"error: Failed to load asset catalog at: '{}'".format(
asset_catalog_path,
),
)
description='.xib / .storyboard linter',
epilog=make_epilog_text(),
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("-v", "--version", action="version",
version=__version__)
parser.add_argument("--reporter", choices=("raw", "json"),
default="raw",
help="custom reporter to use")
parser.add_argument("paths", nargs=argparse.REMAINDER,
help="lint only at the specified paths")
args = parser.parse_args()
try:
from xiblint.config import Config
config = Config()
except IOError as ex:
print('Error: {}\n'.format(ex))
parser.print_usage()
sys.exit(1)
except ValueError as ex:
print('Error: {}: {}\n'.format(Config.filename, ex))
parser.print_usage()
sys.exit(1)
#
# Process paths
#
errors = []
include_paths = args.paths or config.include_paths
for path in include_paths:
if os.path.isfile(path):
parser.add_argument("--reporter", choices=("raw", "json"),
default="raw",
help="custom reporter to use")
parser.add_argument("paths", nargs=argparse.REMAINDER,
help="lint only at the specified paths")
args = parser.parse_args()
try:
from xiblint.config import Config
config = Config()
except IOError as ex:
print('Error: {}\n'.format(ex))
parser.print_usage()
sys.exit(1)
except ValueError as ex:
print('Error: {}: {}\n'.format(Config.filename, ex))
parser.print_usage()
sys.exit(1)
#
# Process paths
#
errors = []
include_paths = args.paths or config.include_paths
for path in include_paths:
if os.path.isfile(path):
errors += process_file(path, config)
elif os.path.isdir(path):
for root, _, files in os.walk(path):
for filename in files:
if os.path.splitext(filename)[1].lower() in ('.storyboard', '.xib'):
file_path = os.path.join(root, filename)
def make_epilog_text():
import xiblint.rules
description = "Lint rules:\n"
for rule_name in sorted(xiblint.rules.rule_checkers.keys()):
checker = xiblint.rules.rule_checkers[rule_name]
description += "\t{}\n".format(rule_name)
doc = checker.__doc__
if doc is not None:
for line in doc.strip().split("\n"):
description += " " * 24 + "{}\n".format(line.strip())
return description
def make_epilog_text():
import xiblint.rules
description = "Lint rules:\n"
for rule_name in sorted(xiblint.rules.rule_checkers.keys()):
checker = xiblint.rules.rule_checkers[rule_name]
description += "\t{}\n".format(rule_name)
doc = checker.__doc__
if doc is not None:
for line in doc.strip().split("\n"):
description += " " * 24 + "{}\n".format(line.strip())
return description
def main():
from patch_element_tree import patch_element_tree
patch_element_tree()
parser = argparse.ArgumentParser(
description='.xib / .storyboard linter',
epilog=make_epilog_text(),
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("-v", "--version", action="version",
version=__version__)
parser.add_argument("--reporter", choices=("raw", "json"),
default="raw",
help="custom reporter to use")
parser.add_argument("paths", nargs=argparse.REMAINDER,
help="lint only at the specified paths")
args = parser.parse_args()
try:
from xiblint.config import Config
config = Config()
except IOError as ex:
print('Error: {}\n'.format(ex))
parser.print_usage()
sys.exit(1)
except ValueError as ex:
print('Error: {}: {}\n'.format(Config.filename, ex))
from xiblint.rules import Rule
from xiblint.xibcontext import XibContext
from xiblint.xibutils import (
view_is_accessibility_element,
view_accessibility_label,
get_view_user_defined_attr,
)
class AccessibilityLabelsForImages(Rule):
"""
Checks for accessible images with no accessibility label.
In this case, VoiceOver will announce the image asset's name, which might be unwanted.
"""
def check(self, context): # type: (XibContext) -> None
for image_view in context.tree.findall(".//imageView"):
if (
view_is_accessibility_element(image_view) is True and
not view_accessibility_label(image_view) and
not get_view_user_defined_attr(image_view, 'accessibilityFormat')
):
context.error(image_view, "Image is accessible but has no accessibility label")
from xiblint.rules import Rule
from xiblint.xibcontext import XibContext
class StrictFontSizes(Rule):
"""
Ensures fonts are in the allowed set.
Example configuration:
{
"minimum_size": 13,
"maximum_size": 30
}
"""
def check(self, context): # type: (XibContext) -> None
minimum_size = self.config.get('minimum_size', 0)
maximum_size = self.config.get('maximum_size', 1000)
for element in context.tree.findall('.//font') + context.tree.findall('.//fontDescription'):
attribute_name = None
from xiblint.rules import Rule
from xiblint.xibcontext import XibContext
class NoTraitVariations(Rule):
"""
Checks for Trait Variations being enabled.
"""
def check(self, context): # type: (XibContext) -> None
root = context.tree.getroot()
if root.get('useTraitCollections') == 'YES' and root.get('targetRuntime') != 'watchKit':
context.error(root, "Document has 'Use Trait Variations' enabled")
from xml.etree.ElementTree import Element
from xiblint.rules import Rule
from xiblint.xibcontext import XibContext
class UnavailableCustomClasses(Rule):
"""
Ensures a given custom class isn't used and provides a replacement suggestion.
You must specify a module as part of the class name.
Example configuration:
{
"custom_classes": {
"SomeModule.LegacyButton": "SomeModule.NewButton"
}
}
"""
def check(self, context): # type: (XibContext) -> None
unavailable_classes = self.config.get('custom_classes', {})
for element in context.tree.findall('.//*[@customClass]'):