#!/usr/bin/python # -*- coding: utf-8 -*- import os import subprocess import sys import tempfile import time def find_dominating_file(dir, file): """Find directory containing file.""" if os.path.exists(os.path.join(dir, file)): return dir return find_dominating_file(os.path.dirname(dir), file) def get_gradle_command(dir): """Find top-project gradlew or fallback to using gradle on sub-project dir.""" topdir = find_dominating_file(dir, 'gradlew') if topdir: return [os.path.join(topdir, 'gradlew'), '-p', topdir] topdir = find_dominating_file(dir, 'build.gradle') if topdir: return ['gradle', '-p', topdir] return ['gradle'] def filter_source_files(files): """Remove any item not looking like a Java source file.""" return [f for f in files if f.endswith('.java')] def run_javac(encoding, source, target, bootcp, cp, files, output, args, sourcefile): """Execute javac with the given options.""" command = ['javac'] if encoding: command.extend(['-encoding', encoding]) if source: command.extend(['-source', source]) if target: command.extend(['-target', target]) if bootcp: command.extend(['-bootclasspath', bootcp]) if cp: command.extend(['-cp', ':'.join(cp)]) if output: command.extend(['-d', output]) command.extend(args) command.append(sourcefile) with tempfile.NamedTemporaryFile(mode='w') as f: command.append('@' + f.name) for source in filter_source_files(files): f.write(source) f.write('\n') f.flush() return subprocess.call(command) def file_in_list(needle, files): """Find needle in files and if so, return the list without needle. Otherwise return None.""" for i in range(0, len(files) - 1): if os.path.samefile(needle, files[i]): return files[0:i] + files[i + 1:] return None def figure_out_java_compilation(sourcefile, tempfile): """Get options for Java compilation from gradle project and run javac.""" cmd = get_gradle_command(os.path.dirname(sourcefile)) cmd.extend(['-q', 'flycheckAndroidJava']) output = subprocess.check_output(cmd, universal_newlines=True).split('\n') data = None for line in output: if line == '***': if data: files = file_in_list(sourcefile, data['files']) if files: return run_javac(data['encoding'], data['source'], data['target'], data['bootcp'], data['cp'], files, data['output'], data['args'], tempfile) data = {} elif data != None: if line.startswith('args='): data['args'] = line[6:-1].split(', ') elif line.startswith('encoding='): data['encoding'] = line[9:] elif line.startswith('bootcp='): data['bootcp'] = line[7:] elif line.startswith('cp='): data['cp'] = line[3:].split(':') elif line.startswith('source='): data['source'] = line[7:] elif line.startswith('target='): data['target'] = line[7:] elif line.startswith('files='): data['files'] = line[6:].split(':') elif line.startswith('output='): data['output'] = line[7:] if data: files = file_in_list(sourcefile, data['files']) if files: return run_javac(data['encoding'], data['source'], data['target'], data['bootcp'], data['cp'], files, data['output'], data['args'], tempfile) return 0 if len(sys.argv) == 3: sys.exit(figure_out_java_compilation(os.path.abspath(sys.argv[1]), sys.argv[2])) elif len(sys.argv) == 2: sys.exit(figure_out_java_compilation(os.path.abspath(sys.argv[1]), sys.argv[1])) else: sys.exit(-1)