Mercurial > hg > truffle
comparison mxtool/mx.py @ 15274:1ea79f17ab95
mx: generalized workaround for system command line length limits and used it to fix issue with eclipseformat command
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 23 Apr 2014 00:54:41 +0200 |
parents | 7be43cbf3568 |
children | 43aa6a7e60bd |
comparison
equal
deleted
inserted
replaced
15273:dec74cb2ec27 | 15274:1ea79f17ab95 |
---|---|
2056 | 2056 |
2057 if suppliedParser: | 2057 if suppliedParser: |
2058 return args | 2058 return args |
2059 return None | 2059 return None |
2060 | 2060 |
2061 def _chunk_files_for_command_line(files, limit=None, pathFunction=None): | |
2062 """ | |
2063 Returns a generator for splitting up a list of files into chunks such that the | |
2064 size of the space separated file paths in a chunk is less than a given limit. | |
2065 This is used to work around system command line length limits. | |
2066 """ | |
2067 chunkSize = 0 | |
2068 chunkStart = 0 | |
2069 if limit is None: | |
2070 commandLinePrefixAllowance = 3000 | |
2071 if get_os() == 'windows': | |
2072 # The CreateProcess function on Windows limits the length of a command line to | |
2073 # 32,768 characters (http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx) | |
2074 limit = 32768 - commandLinePrefixAllowance | |
2075 else: | |
2076 # Using just SC_ARG_MAX without extra downwards adjustment | |
2077 # results in "[Errno 7] Argument list too long" on MacOS. | |
2078 syslimit = os.sysconf('SC_ARG_MAX') - 20000 | |
2079 limit = syslimit - commandLinePrefixAllowance | |
2080 for i in range(len(files)): | |
2081 path = files[i] if pathFunction is None else pathFunction(files[i]) | |
2082 size = len(path) + 1 | |
2083 if chunkSize + size < limit: | |
2084 chunkSize += size | |
2085 else: | |
2086 assert i > chunkStart | |
2087 yield files[chunkStart:i] | |
2088 chunkStart = i | |
2089 chunkSize = 0 | |
2090 if chunkStart == 0: | |
2091 assert chunkSize < limit | |
2092 yield files | |
2093 | |
2061 def eclipseformat(args): | 2094 def eclipseformat(args): |
2062 """run the Eclipse Code Formatter on the Java sources | 2095 """run the Eclipse Code Formatter on the Java sources |
2063 | 2096 |
2064 The exit code 1 denotes that at least one file was modified.""" | 2097 The exit code 1 denotes that at least one file was modified.""" |
2065 | 2098 |
2158 | 2191 |
2159 res = batches.setdefault(batch.settings(), batch) | 2192 res = batches.setdefault(batch.settings(), batch) |
2160 if res is not batch: | 2193 if res is not batch: |
2161 res.javafiles = res.javafiles + batch.javafiles | 2194 res.javafiles = res.javafiles + batch.javafiles |
2162 | 2195 |
2163 print "we have: " + str(len(batches)) + " batches" | 2196 log("we have: " + str(len(batches)) + " batches") |
2164 for batch in batches.itervalues(): | 2197 for batch in batches.itervalues(): |
2165 run([args.eclipse_exe, | 2198 for chunk in _chunk_files_for_command_line(batch.javafiles, pathFunction=lambda f: f.path): |
2166 '-nosplash', | 2199 run([args.eclipse_exe, |
2167 '-application', | 2200 '-nosplash', |
2168 'org.eclipse.jdt.core.JavaCodeFormatter', | 2201 '-application', |
2169 '-vm', java(batch.javaCompliance).java, | 2202 'org.eclipse.jdt.core.JavaCodeFormatter', |
2170 '-config', batch.path] | 2203 '-vm', java(batch.javaCompliance).java, |
2171 + [f.path for f in batch.javafiles]) | 2204 '-config', batch.path] |
2172 for fi in batch.javafiles: | 2205 + [f.path for f in chunk]) |
2173 if fi.update(batch.removeTrailingWhitespace): | 2206 for fi in chunk: |
2174 modified.append(fi) | 2207 if fi.update(batch.removeTrailingWhitespace): |
2208 modified.append(fi) | |
2175 | 2209 |
2176 log('{0} files were modified'.format(len(modified))) | 2210 log('{0} files were modified'.format(len(modified))) |
2177 | 2211 |
2178 if len(modified) != 0: | 2212 if len(modified) != 0: |
2179 arcbase = _primary_suite.dir | 2213 arcbase = _primary_suite.dir |
2501 | 2535 |
2502 auditfileName = join(p.dir, 'checkstyleOutput.txt') | 2536 auditfileName = join(p.dir, 'checkstyleOutput.txt') |
2503 log('Running Checkstyle on {0} using {1}...'.format(sourceDir, config)) | 2537 log('Running Checkstyle on {0} using {1}...'.format(sourceDir, config)) |
2504 | 2538 |
2505 try: | 2539 try: |
2506 | 2540 for chunk in _chunk_files_for_command_line(javafilelist): |
2507 # Checkstyle is unable to read the filenames to process from a file, and the | |
2508 # CreateProcess function on Windows limits the length of a command line to | |
2509 # 32,768 characters (http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx) | |
2510 # so calling Checkstyle must be done in batches. | |
2511 while len(javafilelist) != 0: | |
2512 i = 0 | |
2513 size = 0 | |
2514 while i < len(javafilelist): | |
2515 s = len(javafilelist[i]) + 1 | |
2516 if size + s < 30000: | |
2517 size += s | |
2518 i += 1 | |
2519 else: | |
2520 break | |
2521 | |
2522 batch = javafilelist[:i] | |
2523 javafilelist = javafilelist[i:] | |
2524 try: | 2541 try: |
2525 run_java(['-Xmx1g', '-jar', library('CHECKSTYLE').get_path(True), '-f', 'xml', '-c', config, '-o', auditfileName] + batch, nonZeroIsFatal=False) | 2542 run_java(['-Xmx1g', '-jar', library('CHECKSTYLE').get_path(True), '-f', 'xml', '-c', config, '-o', auditfileName] + chunk, nonZeroIsFatal=False) |
2526 finally: | 2543 finally: |
2527 if exists(auditfileName): | 2544 if exists(auditfileName): |
2528 errors = [] | 2545 errors = [] |
2529 source = [None] | 2546 source = [None] |
2530 def start_element(name, attrs): | 2547 def start_element(name, attrs): |