#!/usr/bin/env python2
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Validates a given master configuration

This enforces various rules defined by the master configuration. Some of these
are fairly simple (the valid properties and subnodes for each node, the
allowable values for properties) and some are more complex (where phandles
are allowed to point).

The schema is defined by Python objects containing variable SchemaElement
subclasses. Each subclass defines how the device tree property is validated.
For strings this is via a regex. Phandles properties are validated by the
target they are expected to point to.

Schema elements can be optional or required. Optional elements will not cause
a failure if the node does not include them.

The presence or absense of a particular schema element can also be controlled
by a 'conditional_props' option. This lists elements that must (or must not)
be present in the node for this element to be present. This provides some
flexibility where the schema for a node has two options, for example, where
the presence of one element conflicts with the presence of others.

Usage:
  The validator can be run like this (set PYTHONPATH to your chromium dir):

  PYTHONPATH=~/cosarm ./validate_config \
      ~/cosarm/chroot/build/coral/usr/share/chromeos-config/config.dtb \
      ~/cosarm/chroot/build/reef-uni/usr/share/chromeos-config/config.dtb \
      README.md

  The output format for each input file is the name of the file followed by a
  list of validation problems. If there are no problems, the filename is not
  shown.

  Unit tests can be run like this:

  PYTHONPATH=~/cosarm python validate_config_unittest.py
"""

from __future__ import print_function

import argparse
import copy
import itertools
import os
import re
import sys

from chromite.lib import cros_build_lib

from . import fdt, fdt_util
from .validate_schema import NodeAny, NodeDesc, NodeModel, NodeSubmodel
from .validate_schema import PropCustom, PropDesc, PropString, PropStringList
from .validate_schema import PropPhandleTarget, PropPhandle, CheckPhandleTarget
from .validate_schema import PropAny, PropBool, PropFile, PropFloat


def ParseArgv(argv):
  """Parse the available arguments.

  Invalid arguments or -h cause this function to print a message and exit.

  Args:
    argv: List of string arguments (excluding program name / argv[0])

  Returns:
    argparse.Namespace object containing the attributes.
  """
  parser = argparse.ArgumentParser(description=__doc__)
  parser.add_argument('-d', '--debug', action='store_true',
                      help='Run in debug mode (full exception traceback)')
  parser.add_argument('-p', '--partial', action='store_true',
                      help='Validate a list partial files (.dtsi) individually')
  parser.add_argument('-r', '--raise-on-error', action='store_true',
                      help='Causes the validator to raise on the first ' +
                      'error it finds. This is useful for debugging.')
  parser.add_argument('config', type=str, nargs='+',
                      help='Paths to the config files (.dtb) to validated')
  return parser.parse_args(argv)


class CrosConfigValidator(object):
  """Validator for the master configuration"""
  def __init__(self, schema, raise_on_error):
    """Master configuration validator.

    Properties:
      _errors: List of validation errors detected (each a string)
      _fdt: fdt.Fdt object containing device tree to validate
      _raise_on_error: True if the validator should raise on the first error
          (useful for debugging)
      model_list: List of model names found in the config
      submodel_list: Dict of submodel names found in the config:
          key: Model name
          value: List of submodel names
    """
    self._errors = []
    self._fdt = None
    self._raise_on_error = raise_on_error
    self._schema = schema

    # This iniital value matches the standard schema object. This is
    # overwritten by the real model list by Start().
    self.model_list = ['MODEL']
    self.submodel_list = {}

  def Fail(self, location, msg):
    """Record a validation failure

    Args:
      location: fdt.Node object where the error occurred
      msg: Message to record for this failure
    """
    self._errors.append('%s: %s' % (location, msg))
    if self._raise_on_error:
      raise ValueError(self._errors[-1])

  def ElementPresent(self, schema, parent_node):
    """Check whether a schema element should be present

    This handles the conditional_props feature. The list of names of sibling
    nodes/properties that are actually present is checked to see if any of them
    conflict with the conditional properties for this node. If there is a
    conflict, then this element is considered to be absent.

    Args:
      schema: Schema element to check
      parent_node: Parent fdt.Node containing this schema element (or None if
          this is not known)

    Returns:
      True if this element is present, False if absent
    """
    if schema.conditional_props and parent_node:
      for rel_name, value in schema.conditional_props.iteritems():
        name = rel_name
        schema_target = schema.parent
        node_target = parent_node
        while name.startswith('../'):
          schema_target = schema_target.parent
          node_target = node_target.parent
          name = name[3:]
        parent_props = [e.name for e in schema_target.elements]
        sibling_names = node_target.props.keys()
        sibling_names += [n.name for n in node_target.subnodes.values()]
        if name in parent_props and value != (name in sibling_names):
          return False
    return True

  def GetElement(self, schema, name, node, expected=None):
    """Get an element from the schema by name

    Args:
      schema: Schema element to check
      name: Name of element to find (string)
      node: Node containing the property (or for nodes, the parent node
          containing the subnode) we are looking up. None if none available
      expected: The SchemaElement object that is expected. This can be NodeDesc
          if a node is expected, PropDesc if a property is expected, or None
          if either is fine.

    Returns:
      Tuple:
        Schema for the node, or None if none found
        True if the node should have schema, False if it can be ignored
            (because it is internal to the device-tree format)
    """
    for element in schema.elements:
      if not self.ElementPresent(element, node):
        continue
      if element.name == name:
        return element, True
      elif (self.model_list and isinstance(element, NodeModel) and
            name in self.model_list):
        return element, True
      elif self.submodel_list and isinstance(element, NodeSubmodel) and node:
        m = re.match('/chromeos/models/([a-z0-9]+)/submodels', node.path)
        if m and name in self.submodel_list[m.group(1)]:
          return element, True
      elif ((expected is None or expected == NodeDesc) and
            isinstance(element, NodeAny)):
        return element, True
      elif ((expected is None or expected == PropDesc) and
            isinstance(element, PropAny)):
        return element, True
    if expected == PropDesc:
      if name == 'linux,phandle':
        return None, False
    return None, True

  def GetElementByPath(self, path):
    """Find a schema element given its full path

    Args:
      path: Full path to look up (e.g. '/chromeos/models/MODEL/thermal/dptf-dv')

    Returns:
      SchemaElement object for that path

    Raises:
      AttributeError if not found
    """
    parts = path.split('/')[1:]
    schema = self._schema
    for part in parts:
      element, _ = self.GetElement(schema, part, None)
      schema = element
    return schema

  def _ValidateSchema(self, node, schema):
    """Simple validation of properties.

    This only handles simple mistakes like getting the name wrong. It
    cannot handle relationships between different properties.

    Args:
      node: fdt.Node where the property appears
      schema: NodeDesc containing schema for this node
    """
    schema.Validate(self, node)
    schema_props = [e.name for e in schema.elements
                    if isinstance(e, PropDesc) and
                    self.ElementPresent(e, node)]

    # Validate each property and check that there are no extra properties not
    # mentioned in the schema.
    for prop_name in node.props.keys():
      if prop_name == 'linux,phandle':  # Ignore this (use 'phandle' instead)
        continue
      element, _ = self.GetElement(schema, prop_name, node, PropDesc)
      if not element or not isinstance(element, PropDesc):
        if prop_name == 'phandle':
          self.Fail(node.path, 'phandle target not valid for this node')
        else:
          self.Fail(node.path, "Unexpected property '%s', valid list is (%s)" %
                    (prop_name, ', '.join(schema_props)))
        continue
      element.Validate(self, node.props[prop_name])

    # Check that there are no required properties which we don't have
    for element in schema.elements:
      if (not isinstance(element, PropDesc) or
          not self.ElementPresent(element, node)):
        continue
      if element.required and element.name not in node.props.keys():
        self.Fail(node.path, "Required property '%s' missing" % element.name)

    # Check that any required subnodes are present
    subnode_names = [n.name for n in node.subnodes.values()]
    for element in schema.elements:
      if (not isinstance(element, NodeDesc) or not element.required
          or not self.ElementPresent(element, node)):
        continue
      if element.name not in subnode_names:
        msg = "Missing subnode '%s'" % element.name
        if subnode_names:
          msg += ' in %s' % ', '.join(subnode_names)
        self.Fail(node.path, msg)

  def GetSchema(self, node, parent_schema):
    """Obtain the schema for a subnode

    This finds the schema for a subnode, by scanning for a matching element.

    Args:
      node: fdt.Node whose schema we are searching for
      parent_schema: Schema for the parent node, which contains that schema

    Returns:
      Schema for the node, or None if none found
    """
    schema, needed = self.GetElement(parent_schema, node.name, node.parent,
                                     NodeDesc)
    if not schema and needed:
      elements = [e.name for e in parent_schema.GetNodes()
                  if self.ElementPresent(e, node.parent)]
      self.Fail(os.path.dirname(node.path),
                "Unexpected subnode '%s', valid list is (%s)" %
                (node.name, ', '.join(elements)))
    return schema

  def _ValidateTree(self, node, parent_schema):
    """Validate a node and all its subnodes recursively

    Args:
      node: name of fdt.Node to search for
      parent_schema: Schema for the parent node
    """
    if node.name == '/':
      schema = parent_schema
    else:
      schema = self.GetSchema(node, parent_schema)
      if schema is None:
        return

    self._ValidateSchema(node, schema)
    for subnode in node.subnodes.values():
      self._ValidateTree(subnode, schema)

  @staticmethod
  def ValidateSkuMap(val, prop):
    it = iter(prop.value)
    sku_set = set()
    for sku, phandle in itertools.izip(it, it):
      sku_id = fdt_util.fdt32_to_cpu(sku)
      # Allow a SKU ID of -1 as a valid match.
      if sku_id > 255 and sku_id != 0xffffffff:
        val.Fail(prop.node.path, 'sku_id %d out of range' % sku_id)
      if sku_id in sku_set:
        val.Fail(prop.node.path, 'Duplicate sku_id %d' % sku_id)
      sku_set.add(sku_id)
      phandle_val = fdt_util.fdt32_to_cpu(phandle)
      target = prop.fdt.LookupPhandle(phandle_val)
      if (not CheckPhandleTarget(val, target, '/chromeos/models/MODEL') and
          not CheckPhandleTarget(val, target,
                                 '/chromeos/models/MODEL/submodels/SUBMODEL')):
        val.Fail(prop.node.path,
                 "Phandle '%s' sku-id %d must target a model or submodel'" %
                 (prop.name, sku_id))

  def GetModelTargetDir(self, path, prop_name):
    """Get the target directory for a given path and property

    This looks up the model schema for a given path and property, and locates
    the target directory for that property.

    Args:
      path: Path within model schema to examine (e.g. /thermal)
      prop_name: Property name to examine (e.g. 'dptf-dv')

    Returns:
      target directory for that property (e.g. '/etc/dptf')
    """
    element = self.GetElementByPath(
        '/chromeos/models/MODEL%s/%s' % (path, prop_name))
    return element.target_dir

  def Prepare(self, _fdt):
    """Locate all the models and submodels before we start"""
    self._fdt = _fdt
    models = self._fdt.GetNode('/chromeos/models')
    for model in models.subnodes.values():
      self.model_list.append(model.name)
      sub_models = model.FindNode('submodels')
      if sub_models:
        self.submodel_list[model.name] = (
            [sm.name for sm in sub_models.subnodes.values()])
      else:
        self.submodel_list[model.name] = []


  def Start(self, fnames, partial=False):
    """Start validating a master configuration file

    Args:
      fnames: List of filenames containing the configuration to validate.
          Supports compiled .dtb files, source .dts files and README.md (which
          has configuration source between ``` markers). If partial is False
          then there can be only one filename in the list.
      partial: True to process a list of partial config files (.dtsi)
    """
    tmpfile = None
    self.model_list = []
    self.submodel_list = {}
    self._errors = []
    try:
      if partial:
        dtb, tmpfile = fdt_util.CompileAll(fnames)
      else:
        dtb, tmpfile = fdt_util.EnsureCompiled(fnames[0])
      self.Prepare(fdt.FdtScan(dtb))

      # Validate the entire master configuration
      self._ValidateTree(self._fdt.GetRoot(), self._schema)
    finally:
      if tmpfile:
        os.unlink(tmpfile.name)
    return self._errors

  @classmethod
  def AddElementTargetDirectories(cls, target_dirs, parent):
    if isinstance(parent, PropFile):
      if parent.name in target_dirs:
        if target_dirs[parent.name] != parent.target_dir:
          raise ValueError(
              "Path for element '%s' is inconsistent with previous path '%s'" %
              (parent.target_dir, target_dirs[parent.name]))
      else:
        target_dirs[parent.name] = parent.target_dir
    if isinstance(parent, NodeDesc):
      for element in parent.elements:
        cls.AddElementTargetDirectories(target_dirs, element)

  def GetTargetDirectories(self):
    """Gets a dict of directory targets for each PropFile property

    Returns:
      Dict:
        key: Property name
        value: Ansolute path for this property
    """
    target_dirs = {}
    self.AddElementTargetDirectories(target_dirs, self._schema)
    return target_dirs

  @classmethod
  def AddElementPhandleProps(cls, phandle_props, parent):
    if isinstance(parent, PropPhandle):
      phandle_props.add(parent.name)
    elif isinstance(parent, NodeDesc):
      for element in parent.elements:
        cls.AddElementPhandleProps(phandle_props, element)

  def GetPhandleProps(self):
    """Gets a set of properties which are used as phandles

    Some properties are used as phandles to link to shared config. This returns
    a set of such properties. Note that 'default' is a special case here
    because it is not a simple phandle link. It locates notes and properties
    anywhere in the linked model. So we need to exclude it from this list so
    that the 'default' handling works correctly.

    Returns:
      set of property names, each a string
    """
    phandle_props = set()
    self.AddElementPhandleProps(phandle_props, self._schema)
    phandle_props.discard('default')
    return phandle_props


# Known directories for installation
CRAS_CONFIG_DIR = '/etc/cras'
UCM_CONFIG_DIR = '/usr/share/alsa/ucm'
LIB_FIRMWARE = '/lib/firmware'
TOUCH_FIRMWARE = '/opt/google/touch/firmware'
# In order not to pollute the regular /usr/sbin with model specific files
# putting the files underneath chromeos-config
ARC_SBIN_DIR = '/usr/share/chromeos-config/sbin'

# Basic firmware schema, which is augmented depending on the situation.
FW_COND = {'shares': False, '../whitelabel': False}

BASE_FIRMWARE_SCHEMA = [
    PropString('bcs-overlay', True, 'overlay-.*', FW_COND),
    PropString('ec-image', False, r'bcs://.*\.tbz2', FW_COND),
    PropString('main-image', False, r'bcs://.*\.tbz2', FW_COND),
    PropString('main-rw-image', False, r'bcs://.*\.tbz2', FW_COND),
    PropString('pd-image', False, r'bcs://.*\.tbz2', FW_COND),
    PropStringList('extra', False,
                   r'(\${(FILESDIR|SYSROOT)}/[a-z/]+)|' +
                   r'(bcs://[A-Za-z0-9\.]+\.tbz2)', FW_COND),
    ]

# Firmware build targets schema, defined here since it is used in a few places.
BUILD_TARGETS_SCHEMA = NodeDesc('build-targets', True, elements=[
    PropString('coreboot', True),
    PropString('ec', True),
    PropString('depthcharge', True),
    PropString('libpayload', True),
    PropString('cr50'),
], conditional_props={'shares': False, '../whitelabel': False})

BASE_AUDIO_SCHEMA = [
    PropString('card', True, '', {'audio-type': False}),
    PropFile('volume', True, '', {'audio-type': False}, CRAS_CONFIG_DIR),
    PropFile('dsp-ini', True, '', {'audio-type': False}, CRAS_CONFIG_DIR),
    PropFile('hifi-conf', True, '', {'audio-type': False}, UCM_CONFIG_DIR),
    PropFile('alsa-conf', True, '', {'audio-type': False}, UCM_CONFIG_DIR),
    PropString('topology-name', False, r'\w+'),
    PropFile('topology-bin', False, '', {'audio-type': False}, LIB_FIRMWARE),

    # TODO(sjg@chromium.org): There is no validation that we have these two.
    # They must both exist either in the model's audio node or here.
    PropFile('cras-config-dir', False, r'[\w${}]+', target_dir=CRAS_CONFIG_DIR),
    PropString('ucm-suffix', False, r'[\w${}]+'),
]

ARC_PROPERTIES_SCHEMA = [
    PropString('product', False, '[a-z0-9]+', {'../whitelabel': False}),
    PropString('device', False, '[{}a-z0-9_]+', {'../whitelabel': False}),
    PropString('oem', False),
    PropString('marketing-name', False),
    PropString('metrics-tag', False),
]

BASE_AUDIO_NODE = [
    NodeAny(r'main', [
        PropPhandle('audio-type', '/chromeos/family/audio/ANY',
                    False),
    ] + BASE_AUDIO_SCHEMA)
]

BASE_POWER_SCHEMA = [
    PropString('charging-ports'),
    PropFloat('keyboard-backlight-no-als-brightness', False, (0, 100)),
    PropFloat('low-battery-shutdown-percent', False, (0, 100)),
    PropFloat('power-supply-full-factor', False, (0.001, 1.0)),
    PropString('set-wifi-transmit-power-for-tablet-mode', False, '0|1'),
    PropString('suspend-to-idle', False, '0|1'),
]

NOT_WL = {'whitelabel': False}

"""This is the schema. It is a hierarchical set of nodes and properties, just
like the device tree. If an object subclasses NodeDesc then it is a node,
possibly with properties and subnodes.

In this way it is possible to describe the schema in a fairly natural,
hierarchical way.
"""
SCHEMA = NodeDesc('/', True, [
    NodeDesc('chromeos', True, [
        NodeDesc('family', True, [
            NodeDesc('audio', elements=[
                NodeAny('', [PropPhandleTarget()] +
                        copy.deepcopy(BASE_AUDIO_SCHEMA)),
            ]),
            NodeDesc('bcs', False, [
                NodeAny('', [
                    PropPhandleTarget(),
                    PropString('overlay', False, 'overlay-.*'),
                    PropString('package'),
                    PropString('tarball'),
                    PropString('ebuild-version', False, '[-.0-9r]+'),
                ]),
            ]),
            NodeDesc('power', elements=[
                NodeAny('', [PropPhandleTarget()] +
                        copy.deepcopy(BASE_POWER_SCHEMA)),
            ]),
            NodeDesc('arc', elements=[
                NodeDesc('build-properties', elements=[
                    NodeAny('', [PropPhandleTarget()] +
                            copy.deepcopy(ARC_PROPERTIES_SCHEMA)),
                ]),
            ]),
            NodeDesc('firmware', elements=[
                PropString('script', True, r'updater4\.sh'),
                NodeAny('', [
                    PropPhandleTarget(),
                    copy.deepcopy(BUILD_TARGETS_SCHEMA),
                    ] + copy.deepcopy(BASE_FIRMWARE_SCHEMA))
            ]),
            NodeDesc('touch', False, [
                NodeAny('', [
                    PropPhandleTarget(),
                    PropPhandle('bcs-type', '/chromeos/family/bcs/ANY'),
                    PropFile('firmware-bin', True, target_dir=TOUCH_FIRMWARE),
                    PropFile('firmware-symlink', True, target_dir=LIB_FIRMWARE),
                    PropString('vendor', True, ''),
                ]),
            ]),
            NodeDesc('mapping', False, [
                NodeAny(r'sku-map(@[0-9])?', [
                    PropString('platform-name', False, ''),
                    PropString('smbios-name-match', False, ''),
                    PropPhandle('single-sku', '/chromeos/models/MODEL', False),
                    PropCustom('simple-sku-map',
                               CrosConfigValidator.ValidateSkuMap, False),
                ]),
            ]),
        ]),
        NodeDesc('models', True, [
            NodeModel([
                PropPhandleTarget(),
                PropPhandle('default', '/chromeos/models/MODEL', False),
                PropPhandle('whitelabel', '/chromeos/models/MODEL', False),
                NodeDesc('firmware', False, [
                    PropPhandle('shares', '/chromeos/family/firmware/ANY',
                                False, {'../whitelabel': False}),
                    PropString(('sig-id-in-customization-id'),
                               conditional_props={'../whitelabel': False}),
                    PropString('key-id', False, '[A-Z][A-Z0-9]+'),
                    PropBool('no-firmware'),
                    copy.deepcopy(BUILD_TARGETS_SCHEMA)
                    ] + copy.deepcopy(BASE_FIRMWARE_SCHEMA)),
                PropString('brand-code', False, '[A-Z]{4}'),
                PropString('powerd-prefs', conditional_props=NOT_WL),
                PropString('test-label', False, '[a-z0-9_]+'),
                PropString('wallpaper', False, '[a-z_]+'),
                NodeDesc('audio', False, copy.deepcopy(BASE_AUDIO_NODE),
                         conditional_props=NOT_WL),
                NodeDesc('arc', False, [
                    PropFile('hw-features', False, '',
                             target_dir=ARC_SBIN_DIR),
                    NodeDesc('build-properties', False, [
                        PropPhandle('arc-properties-type',
                                    '/chromeos/family/arc/build-properties/ANY',
                                    False, {'../whitelabel': False})
                    ] + copy.deepcopy(ARC_PROPERTIES_SCHEMA)),
                ], conditional_props=NOT_WL),
                NodeDesc('power', False, [
                    PropPhandle('power-type', '/chromeos/family/power/ANY',
                                False),
                ] + copy.deepcopy(BASE_POWER_SCHEMA), conditional_props=NOT_WL),
                NodeDesc('submodels', False, [
                    NodeSubmodel([
                        PropPhandleTarget(),
                        NodeDesc('audio', False, copy.deepcopy(BASE_AUDIO_NODE),
                                 conditional_props={'../../audio': False}),
                        NodeDesc('touch', False, [
                            PropString('present', False, r'yes|no|probe'),
                            PropString('probe-regex', False, ''),
                        ]),
                    ])
                ], conditional_props=NOT_WL),
                NodeDesc('thermal', False, [
                    PropFile('dptf-dv', False, r'\w+/dptf.dv',
                             target_dir='/etc/dptf'),
                ], conditional_props=NOT_WL),
                NodeDesc('touch', False, [
                    PropString('present', False, r'yes|no|probe'),
                    # We want to validate that probe-regex is only present when
                    # 'present' = 'probe', but have no way of doing this
                    # currently.
                    PropString('probe-regex', False, ''),
                    NodeAny(r'(stylus|touchpad|touchscreen)(@[0-9])?', [
                        PropPhandle('bcs-type', '/chromeos/family/bcs/ANY'),
                        PropString('pid', False),
                        PropString('version', True),
                        PropPhandle('touch-type', '/chromeos/family/touch/ANY',
                                    False),
                        PropFile('firmware-bin', True, '',
                                 {'touch-type': False},
                                 target_dir=TOUCH_FIRMWARE),
                        PropFile('firmware-symlink', True, '',
                                 {'touch-type': False},
                                 target_dir=LIB_FIRMWARE),
                        PropString('date-code', False),
                    ]),
                ], conditional_props=NOT_WL),
                NodeDesc('whitelabels', False, [
                    NodeAny('', [
                        PropString('brand-code', False, '[A-Z]{4}'),
                        PropString('wallpaper', False, '[a-z_]+'),
                        PropString('key-id', False, '[A-Z][A-Z0-9]+'),
                    ]),
                ], conditional_props=NOT_WL),
            ])
        ]),
        NodeDesc('schema', False, [
            NodeDesc('target-dirs', False, [
                PropAny(),
            ]),
            PropStringList('phandle-properties'),
        ])
    ])
])


def GetValidator():
  """Get a schema validator for use by another module

  Returns:
    CrosConfigValidator object
  """
  return CrosConfigValidator(SCHEMA, raise_on_error=True)


def ShowErrors(fname, errors):
  """Show validation errors

  Args:
    fname: Filename containng the errors
    errors: List of errors, each a string
  """
  print('%s:' % fname, file=sys.stderr)
  for error in errors:
    print(error, file=sys.stderr)
  print(file=sys.stderr)


def Main(argv=None):
  """Main program for validator

  This validates each of the provided files and prints the errors for each, if
  any.

  Args:
    argv: Arguments to the problem (excluding argv[0]); if None, uses sys.argv
  """
  if argv is None:
    argv = sys.argv[1:]
  args = ParseArgv(argv)
  validator = CrosConfigValidator(SCHEMA, args.raise_on_error)
  found_errors = False
  try:
    # If we are given partial files (.dtsi) then we compile them all into one
    # .dtb and validate that.
    if args.partial:
      errors = validator.Start(args.config, partial=True)
      fname = args.config[0]
      if errors:
        ShowErrors(fname, errors)
        found_errors = True

    # Otherwise process each file individually
    else:
      for fname in args.config:
        errors = validator.Start([fname])
        if errors:
          found_errors = True
          if errors:
            ShowErrors(fname, errors)
            found_errors = True
  except cros_build_lib.RunCommandError as e:
    if args.debug:
      raise
    print('Failed: %s' % e, file=sys.stderr)
    found_errors = True
  if found_errors:
    sys.exit(1)


if __name__ == "__main__":
  Main()
