aboutsummaryrefslogtreecommitdiff
path: root/tools/closure_linter-2.3.4/closure_linter/gjslint.py
blob: 7832b8f881b1e921ba0bc68baf072cfc246f8569 (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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env python
# python2.6 for command-line runs using p4lib.  pylint: disable-msg=C6301
#
# Copyright 2007 The Closure Linter Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS-IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Checks JavaScript files for common style guide violations.

gjslint.py is designed to be used as a PRESUBMIT script to check for javascript
style guide violations.  As of now, it checks for the following violations:

  * Missing and extra spaces
  * Lines longer than 80 characters
  * Missing newline at end of file
  * Missing semicolon after function declaration
  * Valid JsDoc including parameter matching

Someday it will validate to the best of its ability against the entirety of the
JavaScript style guide.

This file is a front end that parses arguments and flags.  The core of the code
is in tokenizer.py and checker.py.
"""

__author__ = ('robbyw@google.com (Robert Walker)',
              'ajp@google.com (Andy Perelson)')

import sys
import time

from closure_linter import checker
from closure_linter import errors
from closure_linter.common import errorprinter
from closure_linter.common import simplefileflags as fileflags
import gflags as flags


FLAGS = flags.FLAGS
flags.DEFINE_boolean('unix_mode', False,
                     'Whether to emit warnings in standard unix format.')
flags.DEFINE_boolean('beep', True, 'Whether to beep when errors are found.')
flags.DEFINE_boolean('time', False, 'Whether to emit timing statistics.')
flags.DEFINE_boolean('check_html', False,
                     'Whether to check javascript in html files.')
flags.DEFINE_boolean('summary', False,
                     'Whether to show an error count summary.')
flags.DEFINE_list('additional_extensions', None, 'List of additional file '
                  'extensions (not js) that should be treated as '
                  'JavaScript files.')


GJSLINT_ONLY_FLAGS = ['--unix_mode', '--beep', '--nobeep', '--time',
                      '--check_html', '--summary']


def FormatTime(t):
  """Formats a duration as a human-readable string.

  Args:
    t: A duration in seconds.

  Returns:
    A formatted duration string.
  """
  if t < 1:
    return '%dms' % round(t * 1000)
  else:
    return '%.2fs' % t


def main(argv = None):
  """Main function.

  Args:
    argv: Sequence of command line arguments.
  """
  if argv is None:
    argv = flags.FLAGS(sys.argv)

  if FLAGS.time:
    start_time = time.time()

  suffixes = ['.js']
  if FLAGS.additional_extensions:
    suffixes += ['.%s' % ext for ext in FLAGS.additional_extensions]
  if FLAGS.check_html:
    suffixes += ['.html', '.htm']
  files = fileflags.GetFileList(argv, 'JavaScript', suffixes)

  error_handler = None
  if FLAGS.unix_mode:
    error_handler = errorprinter.ErrorPrinter(errors.NEW_ERRORS)
    error_handler.SetFormat(errorprinter.UNIX_FORMAT)

  runner = checker.GJsLintRunner()
  result = runner.Run(files, error_handler)
  result.PrintSummary()

  exit_code = 0
  if result.HasOldErrors():
    exit_code += 1
  if result.HasNewErrors():
    exit_code += 2

  if exit_code:
    if FLAGS.summary:
      result.PrintFileSummary()

    if FLAGS.beep:
      # Make a beep noise.
      sys.stdout.write(chr(7))

    # Write out instructions for using fixjsstyle script to fix some of the
    # reported errors.
    fix_args = []
    for flag in sys.argv[1:]:
      for f in GJSLINT_ONLY_FLAGS:
        if flag.startswith(f):
          break
      else:
        fix_args.append(flag)

    print """
Some of the errors reported by GJsLint may be auto-fixable using the script
fixjsstyle. Please double check any changes it makes and report any bugs. The
script can be run by executing:

fixjsstyle %s """ % ' '.join(fix_args)

  if FLAGS.time:
    print 'Done in %s.' % FormatTime(time.time() - start_time)

  sys.exit(exit_code)


if __name__ == '__main__':
  main()