summaryrefslogtreecommitdiff
path: root/chromium/tools/metrics/common/presubmit_util.py
blob: e8e1a50bee50c7763e8b2b98bff8942f2c772bee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import difflib
import logging
import os
import shutil
import sys

sys.path.append(
    os.path.join(os.path.dirname(os.path.abspath(__file__)),
                 os.pardir, os.pardir, 'python', 'google'))
import path_utils

import diff_util

def DoPresubmit(argv, original_filename, backup_filename, script_name,
                prettyFn):
  """Execute presubmit/pretty printing for the target file.

  Args:
    argv: command line arguments
    original_filename: The filename to read from.
    backup_filename: When pretty printing, move the old file contents here.
    script_name: The name of the script to run for pretty printing.
    prettyFn: A function which takes the original xml content and produces
        pretty printed xml.

  Returns:
    An exit status.  Non-zero indicates errors.
  """
  # interactive: Print log info messages and prompt user to accept the diff.
  interactive = ('--non-interactive' not in argv)
  # presubmit: Simply print a message if the input is not formatted correctly.
  presubmit = ('--presubmit' in argv)
  # diff: Print diff to stdout rather than modifying files.
  diff = ('--diff' in argv)

  if interactive:
    logging.basicConfig(level=logging.INFO)
  else:
    logging.basicConfig(level=logging.ERROR)

  # If there is a description xml in the current working directory, use that.
  # Otherwise, use the one residing in the same directory as this script.
  xml_dir = os.getcwd()
  if not os.path.isfile(os.path.join(xml_dir, original_filename)):
    xml_dir = path_utils.ScriptDir()

  xml_path = os.path.join(xml_dir, original_filename)

  # Save the original file content.
  logging.info('Loading %s...', os.path.relpath(xml_path))
  with open(xml_path, 'rb') as f:
    original_xml = f.read()

  # Check there are no CR ('\r') characters in the file.
  if '\r' in original_xml:
    logging.error('DOS-style line endings (CR characters) detected - these are '
                  'not allowed. Please run dos2unix %s', original_filename)
    return 1

  try:
    pretty = prettyFn(original_xml)
  except Exception as e:
    logging.exception('Aborting parsing due to fatal errors:')
    return 1

  if original_xml == pretty:
    logging.info('%s is correctly pretty-printed.', original_filename)
    return 0

  if presubmit:
    logging.error('%s is not formatted correctly; run %s to fix.',
                  original_filename, script_name)
    return 1

  # Prompt user to consent on the change.
  if interactive and not diff_util.PromptUserToAcceptDiff(
      original_xml, pretty, 'Is the new version acceptable?'):
    logging.error('Diff not accepted. Aborting.')
    return 1

  if diff:
    for line in difflib.unified_diff(original_xml.splitlines(),
                                     pretty.splitlines()):
      print line
    return 0

  logging.info('Creating backup file: %s', backup_filename)
  shutil.move(xml_path, os.path.join(xml_dir, backup_filename))

  with open(xml_path, 'wb') as f:
    f.write(pretty)
  logging.info('Updated %s. Don\'t forget to add it to your changelist',
               xml_path)
  return 0


def DoPresubmitMain(*args, **kwargs):
  sys.exit(DoPresubmit(*args, **kwargs))