presubmit.py revision a7e24c173cf37484693b9abb38e494fa7bd7baeb
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#!/usr/bin/env python 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# Copyright 2008 the V8 project authors. All rights reserved. 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# Redistribution and use in source and binary forms, with or without 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# modification, are permitted provided that the following conditions are 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# met: 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# * Redistributions of source code must retain the above copyright 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# notice, this list of conditions and the following disclaimer. 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# * Redistributions in binary form must reproduce the above 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# copyright notice, this list of conditions and the following 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# disclaimer in the documentation and/or other materials provided 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# with the distribution. 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# * Neither the name of Google Inc. nor the names of its 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# contributors may be used to endorse or promote products derived 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# from this software without specific prior written permission. 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport optparse 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport os 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfrom os.path import abspath, join, dirname, basename, exists 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport re 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport sys 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockimport subprocess 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# Disabled LINT rules and reason. 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# build/include_what_you_use: Started giving false positives for variables 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block# named "string" and "map" assuming that you needed to include STL headers. 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockENABLED_LINT_RULES = """ 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbuild/class 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbuild/deprecated 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbuild/endif_comment 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbuild/forward_decl 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbuild/include_order 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbuild/printf_format 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbuild/storage_class 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocklegal/copyright 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/boost 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/braces 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/casting 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/check 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/constructors 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/fn_size 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/function 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/multiline_comment 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/multiline_string 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/streams 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/todo 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockreadability/utf8 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/arrays 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/casting 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/deprecated_fn 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/explicit 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/int 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/memset 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/mutex 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/nonconf 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/printf 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/printf_format 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/references 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/rtti 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/sizeof 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/string 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/virtual 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockruntime/vlog 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/blank_line 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/braces 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/comma 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/comments 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/end_of_line 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/ending_newline 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/indent 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/labels 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/line_length 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/newline 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/operators 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/parens 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/tab 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockwhitespace/todo 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block""".split() 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SourceFileProcessor(object): 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """ 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Utility class that can run through a directory structure, find all relevant 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block files and invoke a custom check on the files. 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """ 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def Run(self, path): 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block all_files = [] 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for file in self.GetPathsToSearch(): 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block all_files += self.FindFilesIn(join(path, file)) 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not self.ProcessFiles(all_files, path): 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return True 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IgnoreDir(self, name): 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return name.startswith('.') or name == 'data' 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IgnoreFile(self, name): 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return name.startswith('.') 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def FindFilesIn(self, path): 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = [] 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (root, dirs, files) in os.walk(path): 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for ignored in [x for x in dirs if self.IgnoreDir(x)]: 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block dirs.remove(ignored) 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for file in files: 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not self.IgnoreFile(file) and self.IsRelevant(file): 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.append(join(root, file)) 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CppLintProcessor(SourceFileProcessor): 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """ 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Lint files to check that they follow the google code style. 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """ 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IsRelevant(self, name): 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return name.endswith('.cc') or name.endswith('.h') 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IgnoreDir(self, name): 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (super(CppLintProcessor, self).IgnoreDir(name) 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block or (name == 'third_party')) 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IGNORE_LINT = ['flag-definitions.h'] 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IgnoreFile(self, name): 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (super(CppLintProcessor, self).IgnoreFile(name) 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block or (name in CppLintProcessor.IGNORE_LINT)) 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetPathsToSearch(self): 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ['src', 'public', 'samples', join('test', 'cctest')] 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def ProcessFiles(self, files, path): 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block filt = '-,' + ",".join(['+' + n for n in ENABLED_LINT_RULES]) 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command = ['cpplint.py', '--filter', filt] + join(files) 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block local_cpplint = join(path, "tools", "cpplint.py") 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if exists(local_cpplint): 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block command = ['python', local_cpplint, '--filter', filt] + join(files) 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block process = subprocess.Popen(command) 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return process.wait() == 0 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCOPYRIGHT_HEADER_PATTERN = re.compile( 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block r'Copyright [\d-]*200[8-9] the V8 project authors. All rights reserved.') 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass SourceProcessor(SourceFileProcessor): 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """ 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Check that all files include a copyright notice. 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block """ 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RELEVANT_EXTENSIONS = ['.js', '.cc', '.h', '.py', '.c', 'SConscript', 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'SConstruct', '.status'] 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IsRelevant(self, name): 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for ext in SourceProcessor.RELEVANT_EXTENSIONS: 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if name.endswith(ext): 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return True 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return False 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def GetPathsToSearch(self): 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return ['.'] 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def IgnoreDir(self, name): 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (super(SourceProcessor, self).IgnoreDir(name) 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block or (name == 'third_party') 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block or (name == 'obj')) 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IGNORE_COPYRIGHTS = ['earley-boyer.js', 'raytrace.js', 'crypto.js', 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'libraries.cc', 'libraries-empty.cc', 'jsmin.py', 'regexp-pcre.js'] 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block IGNORE_TABS = IGNORE_COPYRIGHTS + ['unicode-test.js', 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 'html-comments.js'] 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def ProcessContents(self, name, contents): 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = True 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block base = basename(name) 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not base in SourceProcessor.IGNORE_TABS: 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if '\t' in contents: 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "%s contains tabs" % name 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = False 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not base in SourceProcessor.IGNORE_COPYRIGHTS: 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not COPYRIGHT_HEADER_PATTERN.search(contents): 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print "%s is missing a correct copyright header." % name 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = False 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block def ProcessFiles(self, files, path): 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block success = True 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for file in files: 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block try: 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block handle = open(file) 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block contents = handle.read() 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block success = self.ProcessContents(file, contents) and success 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block finally: 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block handle.close() 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return success 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef GetOptions(): 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = optparse.OptionParser() 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result.add_option('--no-lint', help="Do not run cpplint", default=False, 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block action="store_true") 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdef Main(): 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block workspace = abspath(join(dirname(sys.argv[0]), '..')) 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block parser = GetOptions() 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (options, args) = parser.parse_args() 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block success = True 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if not options.no_lint: 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block success = CppLintProcessor().Run(workspace) and success 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block success = SourceProcessor().Run(workspace) and success 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if success: 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 0 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block else: 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return 1 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockif __name__ == '__main__': 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block sys.exit(Main()) 235