# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

"""Top-level presubmit script for Dart.

See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""

def CheckChangeOnCommit(input_api, output_api):
  results = []
  status_check = input_api.canned_checks.CheckTreeIsOpen(
      input_api,
      output_api,
      json_url='http://dart-status.appspot.com/current?format=json')
  results.extend(status_check)
  return results

# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

"""Top-level presubmit script for Dart.

See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into gcl.
"""

import imp
import os
import scm
import subprocess
import tempfile

def _CheckBuildStatus(input_api, output_api):
   results = []
   status_check = input_api.canned_checks.CheckTreeIsOpen(
       input_api,
       output_api,
       json_url='http://dart-status.appspot.com/current?format=json')
   results.extend(status_check)
   return results

def _CheckDartFormat(input_api, output_api):
  local_root = input_api.change.RepositoryRoot()
  upstream = input_api.change._upstream
  utils = imp.load_source('utils',
      os.path.join(local_root, 'tools', 'utils.py'))

  prebuilt_dartfmt = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dartfmt')

  windows = utils.GuessOS() == 'win32'
  if windows:
    prebuilt_dartfmt += '.bat'

  if not os.path.isfile(prebuilt_dartfmt):
    print('WARNING: dartfmt not found: %s' % (prebuilt_dartfmt))
    return []

  def HasFormatErrors(filename=None, contents=None):
    args = [prebuilt_dartfmt, '--set-exit-if-changed']
    if contents:
      process = subprocess.Popen(args,
                                 stdout=subprocess.PIPE,
                                 stdin=subprocess.PIPE
                                 )
      out, err = process.communicate(input=contents)

      # There was a bug in the return code dartfmt returns when reading from
      # stdin so we have to check whether the content matches rather than using
      # the return code. When the next version of the dartfmt lands in the sdk
      # we can switch this line to "return process.returncode != 0"
      return out != contents
    else:
      try:
        subprocess.check_output(args + [filename, '-n'])
      except subprocess.CalledProcessError:
        return True
      return False

  unformatted_files = []
  for git_file in input_api.AffectedTextFiles():
    filename = git_file.AbsoluteLocalPath()
    if filename.endswith('.dart'):
      if HasFormatErrors(filename=filename):
        old_version_has_errors = False
        try:
          path = git_file.LocalPath()
          if windows:
            # Git expects a linux style path.
            path = path.replace(os.sep, '/')
          old_contents = scm.GIT.Capture(
            ['show', upstream + ':' + path],
            cwd=local_root,
            strip_out=False)
          if HasFormatErrors(contents=old_contents):
            old_version_has_errors = True
        except subprocess.CalledProcessError as e:
          # TODO(jacobr): verify that the error really is that the file was
          # added for this CL.
          old_version_has_errors = False

        if old_version_has_errors:
          print("WARNING: %s has existing and possibly new dartfmt issues" %
            git_file.LocalPath())
        else:
          unformatted_files.append(filename)

  if unformatted_files:
    return [output_api.PresubmitError(
        'File output does not match dartfmt.\n'
        'Fix these issues with:\n'
        'dartfmt -w \\\n%s' % ' \\\n'.join(unformatted_files))]

  return []

def CheckChangeOnCommit(input_api, output_api):
  return (_CheckBuildStatus(input_api, output_api) +
          _CheckDartFormat(input_api, output_api))

def CheckChangeOnUpload(input_api, output_api):
  return _CheckDartFormat(input_api, output_api)

Add presubmit check that runs dartfmt