def process_fixer(self, files): """ Autofixing typing errors requires generating type stubs and then applying them individually. """ command = self._apply_options(['pytype']) command += files container_name = self._container_name(files) # run in a container that sticks around so we can # run merge-pyi on the output files. docker.run('pytype', command, source_dir=self.base_path, name=container_name) buildlog.info('Creating cusotm image for pytype') docker.commit(container_name) docker.rm_container(container_name) update_command = ['merge-pyi-wrapper'] update_command += files # Apply merge-pyi try: out = docker.run(container_name, update_command, source_dir=self.base_path) except Exception as e: buildlog.warning('Pytype merging failed. error=%s output=%s', e, out) finally: buildlog.info('Removing custom pytype image') docker.rm_image(container_name)
def process_fixer(self, files): """Run autopep8, as flake8 has no fixer mode. """ command = self.create_fixer_command(files) image = self.get_image_name(files) docker.run(image, command, self.base_path)
def process_fixer(self, files): """Run Eslint in the fixer mode. """ command = self.create_fixer_command(files) image_name = self.get_image_name(files) docker.run(image_name, command, source_dir=self.base_path)
def process_fixer(self, files): """Run stylelint in the fixer mode. """ command = self.create_fixer_command(files) docker.run( 'nodejs', command, source_dir=self.base_path)
def process_fixer(self, files): """Run PHPCS in the fixer mode. """ command = self.create_fixer_command(files) docker.run( 'phpcs', command, source_dir=self.base_path)
def test_run__named_container(self): cmd = ['echo', "things"] docker.run('python2', cmd, test_dir, name='test_container') containers = docker.containers(include_stopped=True) self.assertIn('test_container', containers) docker.rm_container('test_container') containers = docker.containers(include_stopped=True) assert 'test_conainer' not in containers
def process_fixer(self, files): """Run Eslint in the fixer mode. """ command = self.create_fixer_command(files) container_name = self._container_name(files) self.install_plugins(container_name) image_name = container_name or 'eslint' docker.run(image_name, command, source_dir=self.base_path)
def process_fixer(self, files): """Run Eslint in the fixer mode. """ command = self.create_fixer_command(files) container_name = self._container_name(files) self.install_plugins(container_name) image_name = container_name or 'eslint' docker.run( image_name, command, source_dir=self.base_path)
def install_plugins(self, container_name): """Run container command to install eslint plugins """ if not self.options.get('install_plugins', False): return if self.installed_plugins is False: log.info('Installing eslint plugins into %s', container_name) docker.run('eslint', ['eslint-install'], source_dir=self.base_path, name=container_name) docker.commit(container_name) docker.rm_container(container_name) self.installed_plugins = True
def get_image_name(self, files): """Get the image name based on options If the `plugin` option is used a custom image will be created. """ image = python_image(self.options) plugins = self.options.get('plugins', None) if not plugins: return image if not isinstance(plugins, list): plugin_type = plugins.__class__.__name__ error = IssueComment( u'The `flake8.plugins` option must be a list got `{}` instead.'.format( plugin_type ) ) self.problems.add(error) return image invalid_plugins = [ p for p in plugins if p not in self.ALLOWED_PLUGINS] if invalid_plugins: error = IssueComment( u'The `flake8.plugins` option contained unsupported plugins {}'.format( u', '.join(invalid_plugins) ) ) self.problems.add(error) return image container_name = docker.generate_container_name('flake8', files) if self.custom_image is None: buildlog.info('Installing flake8 plugins') docker.run( image, ['flake8-install', u','.join(plugins)], source_dir=self.base_path, name=container_name ) docker.commit(container_name) docker.rm_container(container_name) self.custom_image = container_name buildlog.info('Installed flake8 plugins %s', plugins) return container_name
def process_files(self, files): """ Run code checks with pep8. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) pep8_options = ['exclude', 'filename', 'select', 'ignore', 'max-line-length'] command = ['pep8', '-r'] for option, value in self.options.items(): if option in pep8_options: command += [u'--{}'.format(option), value] command += files image = python_image(self.options) output = docker.run(image, command, source_dir=self.base_path) if not output: log.debug('No pep8 errors found.') return False output = output.split("\n") process_quickfix(self.problems, output, docker.strip_base)
def get_image_name(self, files): """Run container command to install eslint plugins """ if not self.options.get('install_plugins', False): return 'eslint' container_name = docker.generate_container_name('eslint', files) if self.custom_image is None: log.info('Installing eslint plugins into %s', container_name) output = docker.run( 'eslint', ['eslint-install'], source_dir=self.base_path, name=container_name) docker.commit(container_name) docker.rm_container(container_name) self.custom_image = container_name installed = [ line.strip('add:') for line in output.splitlines() if line.startswith('add:') ] log.info('Installed eslint plugins %s', installed) return container_name
def process_files(self, files): """ Run code checks with pep8. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) command = self.create_command() command += map(lambda f: docker.apply_base(f), files) output = docker.run('nodejs', command, source_dir=self.base_path) if not output: return False output = output.split("\n") filename = None # The output from remarklint is a unique format that looks like: # # >>> file.md # >>> 1:1-1:8 warning Some warning # # We inspect each line to determine if it is a file or warning. for line in output: if filename_pattern.match(line): # Remove the base path as remarklint is fed absolute paths. filename = docker.strip_base(line) else: match = warning_pattern.match(line) if match: line = match.group('line') text = match.group('text') self.problems.add(filename, line, text)
def process_files(self, files): """ Run code checks with mypy. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) command = ['mypy', '--no-error-summary', '--show-absolute-path'] if 'config' in self.options: command += ['--config-file', stringify(self.options.get('config'))] command += files output = docker.run('python3', command, source_dir=self.base_path) if not output: log.debug('No mypy errors found.') return False output = output.strip().split("\n") if len(output) and output[-1].startswith('mypy: error:'): msg = ( u'Your `mypy` configuration file caused `mypy` to fail with:' '\n' '```\n' '{}\n' '```\n' 'Please correct the error in your configuration file.') self.problems.add(IssueComment(msg.format(output[-1]))) return process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with credo. """ log.debug('Processing %s files with %s', files, self.name) credo_options = ['checks', 'config-name', 'ignore-checks'] credo_flags = ['all', 'all-priorities', 'strict'] command = ['mix', 'credo', 'list', '--format', 'flycheck'] for option, value in self.options.items(): if option in credo_options: command += [u'--{}'.format(option), value] elif option in credo_flags: if self.parse_ini_bool(value): command += [u'--{}'.format(option)] else: log.error('%s is not a valid option to credo', option) command += files output = docker.run('credo', command, self.base_path) if not output: log.debug('No credo errors found.') return False process_quickfix(self.problems, output.strip().splitlines(), docker.strip_base, columns=4)
def process_files(self, files): """ Run code checks with rubocop """ command = self._create_command() command += files output = docker.run('ruby2', command, self.base_path) if not output: return output = output.split("\n") # rubocop will emit warnings at the beginning of its output. if '.rubocop.yml' in output[0]: warnings = [] for i, line in enumerate(output): # Stack trace when rubocop fails. if line.startswith("/usr/local"): continue # Likely a lint error. elif line.count(":") >= 2: break else: warnings.append(line) msg = [ "Your rubocop configuration output the following error:", "```", "\n".join(warnings), "```", ] self.problems.add(IssueComment("\n".join(msg))) output = output[i:] process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with black. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) command = self.create_command() command.append('--check') command += files output = docker.run('python3', command, source_dir=self.base_path) if not output: return False output = output.split("\n") effected_files = [ '* ' + docker.strip_base(line.replace('would reformat ', '')) for line in output if line.startswith('would reformat') ] if len(effected_files): msg = ( 'The following files do not match the `black` styleguide:' '\n\n' ) msg += "\n".join(effected_files) self.problems.add(IssueComment(msg))
def process_files(self, files): """ Run code checks with yamllint. Only a single process is made for all files to save resources. Configuration is not supported at this time """ command = ['yamllint', '--format=parsable'] # Add config file if its present if self.options.get('config'): command += [ '-c', docker.apply_base(self.options['config']) ] command += files output = docker.run('python2', command, self.base_path) if not output: return False if 'No such file' in output and 'Traceback' in output: error = output.strip().split("\n")[-1] msg = (u'`yamllint` failed with the following error:\n' '```\n' '{}\n' '```\n') return self.problems.add(IssueComment(msg.format(error))) output = output.split("\n") process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with swiftlit. """ log.debug('Processing %s files with %s', files, self.name) command = [ 'swiftlint', 'lint', '--quiet', '--reporter', 'checkstyle', '--use-script-input-files' ] # swiftlint uses a set of environment variables # to lint multiple files at once. env = {} for index, name in enumerate(files): env['SCRIPT_INPUT_FILE_%s' % (index,)] = name env['SCRIPT_INPUT_FILE_COUNT'] = str(len(files)) output = docker.run( 'swiftlint', command, self.base_path, env=env) process_checkstyle(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with checkstyle. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) if 'config' not in self.options: msg = ("We could not run `checkstyle` you did not set " "the `config` option to a valid checkstyle XML file.") return self.problems.add(IssueComment(msg)) command = self.create_command(files) output = docker.run('checkstyle', command, self.base_path) # Only one line is generally a config error. Replay the error # to the user. lines = output.strip().split('\n') if not lines[0].startswith('<'): msg = ("Running `checkstyle` failed with:\n" "```\n" "%s\n" "```\n" "Ensure your config file exists and is valid XML.") return self.problems.add(IssueComment(msg % (lines[0], ))) # Remove the last line if it is not XML # Checkstyle outputs text after the XML if there are errors. if not lines[-1].strip().startswith('<'): lines = lines[0:-1] output = ''.join(lines) process_checkstyle(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with yamllint. Only a single process is made for all files to save resources. Configuration is not supported at this time """ log.debug('Processing %s files with %s', files, self.name) command = ['yamllint', '--format=parsable'] # Add config file if its present if self.options.get('config'): command += [ '-c', docker.apply_base(self.options['config']) ] command += files output = docker.run('python2', command, self.base_path) if not output: log.debug('No yamllint errors found.') return False if 'No such file' in output and 'Traceback' in output: error = output.strip().split("\n")[-1] msg = (u'`yamllint` failed with the following error:\n' '```\n' '{}\n' '```\n') return self.problems.add(IssueComment(msg.format(error))) output = output.split("\n") process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with pep8. Only a single process is made for all files to save resources. """ command = self.create_command() command += map(lambda f: docker.apply_base(f), files) output = docker.run('nodejs', command, source_dir=self.base_path) if not output: return False output = output.split("\n") filename = None # The output from remarklint is a unique format that looks like: # # >>> file.md # >>> 1:1-1:8 warning Some warning # # We inspect each line to determine if it is a file or warning. for line in output: if filename_pattern.match(line): # Remove the base path as remarklint is fed absolute paths. filename = docker.strip_base(line) else: match = warning_pattern.match(line) if match: line = match.group('line') text = match.group('text') self.problems.add(filename, line, text)
def install_plugins(self, container_name): """Run container command to install eslint plugins """ if not self.options.get('install_plugins', False): return if self.installed_plugins is False: log.info('Installing eslint plugins into %s', container_name) docker.run( 'eslint', ['eslint-install'], source_dir=self.base_path, name=container_name) docker.commit(container_name) docker.rm_container(container_name) self.installed_plugins = True
def process_files(self, files): """ Run code checks with shellcheck. """ command = self.create_command(files) output = docker.run('shellcheck', command, self.base_path) process_checkstyle(self.problems, output, docker.strip_base) list(map(self.escape_backtick, self.problems))
def process_files(self, files): """Run code checks with ESLint. """ log.debug('Processing %s files with %s', files, self.name) command = self._create_command() command += files output = docker.run('nodejs', command, source_dir=self.base_path) self._process_output(output, files)
def process_files(self, files): """ Run code checks with shellcheck. """ log.debug('Processing %s files with %s', files, self.name) command = self.create_command(files) output = docker.run('shellcheck', command, self.base_path) process_checkstyle(self.problems, output, docker.strip_base) list(map(self.escape_backtick, self.problems))
def process_files(self, files): """ Run code checks with luacheck. """ log.debug('Processing %s files with %s', files, self.name) command = self.create_command(files) output = docker.run('luacheck', command, self.base_path) output = output.split("\n") process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with ktlint. """ command = self._create_command() command += files output = docker.run('ktlint', command, self.base_path) process_checkstyle(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with jshint. Only a single process is made for all files to save resources. """ command = self.create_command(files) output = docker.run('nodejs', command, source_dir=self.base_path) process_checkstyle(self.problems, output, False)
def process_files(self, files): """ Run code checks with jscs. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) command = self.create_command(files) output = docker.run('nodejs', command, source_dir=self.base_path) process_checkstyle(self.problems, output, None)
def execute_commits(self, commits): """ Check that HEAD commit has gpg signature """ cmd = ['git', 'log', 'HEAD^..HEAD', '--show-signature', '--format=%H'] output = docker.run('gpg', cmd, self.base_path) if 'Signature made' not in output: body = 'No gpg signature for tip of the branch.' self.problems.add(IssueComment(body))
def process_files(self, files): """ Run code checks with XO. """ log.debug('Processing %s files with %s', files, self.name) command = ['xo', '--reporter', 'checkstyle'] command += files output = docker.run('nodejs', command, source_dir=self.base_path) process_checkstyle(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with standard. """ command = ['standard'] + list(files) output = docker.run('nodejs', command, source_dir=self.base_path) output = output.split("\n") output = [line for line in output if not line.startswith('standard')] process_quickfix(self.problems, output, docker.strip_base)
def run_individual_files(self, files, filename_converter): """ If we get an error from golint about different packages we have to re-run golint on each file as figuring out package relations is hard. """ for filename in files: command = self.create_command([filename]) output = docker.run('golint', command, self.base_path) output = output.split("\n") process_quickfix(self.problems, output, filename_converter)
def process_files(self, files): """ Run checks with goodcheck """ command = self._create_command() command += files output = docker.run('ruby2', command, self.base_path) # The last line should contain a JSON document with results # from goodcheck self._process_output(output.strip().split("\n")[-1])
def process_files(self, files): """Run code checks with ESLint. """ command = self._create_command() command += files image_name = self.get_image_name(files) output = docker.run(image_name, command, source_dir=self.base_path) self._cleanup() self._process_output(output, files)
def process_files(self, files): """ Run code checks with flake8. """ command = self.make_command(files) image = self.get_image_name(files) output = docker.run(image, command, source_dir=self.base_path) self._cleanup() output = output.split("\n") process_quickfix(self.problems, output, docker.strip_base)
def execute_commits(self, commits): """ Check that HEAD commit has gpg signature """ cmd = [ 'git', 'log', 'HEAD^..HEAD', '--show-signature', '--format=%H' ] output = docker.run('gpg', cmd, self.base_path) if 'Signature made' not in output: body = 'No gpg signature for tip of the branch.' self.problems.add(IssueComment(body))
def process_files(self, files): """ Run code checks with puppet-lint """ command = self._create_command() command += files output = docker.run('ruby2', command, self.base_path) if not output: return False output = output.split("\n") process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with jshint. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) command = self.create_command(files) output = docker.run( 'nodejs', command, source_dir=self.base_path) process_checkstyle(self.problems, output, False)
def process_files(self, files): """ Run code checks with standard. """ log.debug('Processing %s files with %s', files, self.name) command = ['standard'] + list(files) output = docker.run( 'nodejs', command, source_dir=self.base_path) output = output.split("\n") output = [line for line in output if not line.startswith('standard')] process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with pytype. Only a single process is made for all files to save resources. """ command = self._apply_options(['pytype']) command += files output = docker.run('pytype', command, source_dir=self.base_path) if not output: return self.parse_output(output)
def process_files(self, files): """ Run code checks with TSLint. """ log.debug('Processing %s files with %s', files, self.name) command = ['tslint', '--format', 'checkstyle'] # Add config file or default to recommended linters if self.options.get('config'): command += ['-c', docker.apply_base(self.options['config'])] command += files output = docker.run('nodejs', command, source_dir=self.base_path) self._process_output(output, files)
def process_fixer(self, files): """ Autofixing typing errors requires generating type stubs and then applying them individually. """ command = self._apply_options(['pytype']) command += files container_name = self._container_name(files) # run in a container that sticks around so we can # run merge-pyi on the output files. docker.run( 'python3', command, source_dir=self.base_path, name=container_name) log.info('Creating temporary image for %s', container_name) docker.commit(container_name) docker.rm_container(container_name) update_command = ['merge-pyi-wrapper'] update_command += files # Apply merge-pyi try: out = docker.run( container_name, update_command, source_dir=self.base_path ) except Exception as e: log.warning('Pytype merging failed. error=%s output=%s', e, out) finally: log.info('Removing temporary image for %s', container_name) docker.rm_image(container_name)
def process_files(self, files): """ Run code checks with puppet-lint """ log.debug('Processing %s files with %s', files, self.name) command = self._create_command() command += files output = docker.run('ruby2', command, self.base_path) if not output: log.debug('No puppet-lint errors found.') return False output = output.split("\n") process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with luacheck. """ log.debug('Processing %s files with %s', files, self.name) command = self.create_command(files) output = docker.run('luacheck', command, self.base_path) output = output.split("\n") if len(output) and 'Critical' in output[0]: msg = (u"luacheck failed with the following error:\n" u"```\n" u"{}\n" u"```\n") self.problems.add(IssueComment(msg.format(output[0]))) return process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with flake8. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', len(files), self.name) command = self.make_command(files) image = python_image(self.options) output = docker.run(image, command, source_dir=self.base_path) if not output: log.debug('No flake8 errors found.') return False output = output.split("\n") process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with pylint --py3k. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) command = self.make_command(files) output = docker.run('python2', command, self.base_path) if not output: log.debug('No py3k errors found.') return False output = output.split("\n") output = [line for line in output if not line.startswith("*********")] process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with credo. """ log.debug('Processing %s files with %s', files, self.name) command = self.create_command() command += files output = docker.run('credo', command, self.base_path) if not output: log.debug('No credo errors found.') return False process_quickfix( self.problems, output.strip().splitlines(), docker.strip_base, columns=4)
def process_files(self, files): """Run code checks with ESLint. """ log.debug('Processing %s files with %s', files, self.name) command = self._create_command() command += files container_name = self._container_name(files) self.install_plugins(container_name) image_name = container_name or 'eslint' output = docker.run( image_name, command, source_dir=self.base_path) self._cleanup(container_name) self._process_output(output, files)
def process_files(self, files): """ Run code checks with pytype. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) command = self._apply_options(['pytype']) command += files output = docker.run( 'python3', command, source_dir=self.base_path) if not output: return self.parse_output(output)
def process_files(self, files): """ Run code checks with checkstyle. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) if 'config' not in self.options: msg = ("We could not run `checkstyle` you did not set " "the `config` option to a valid checkstyle XML file.") return self.problems.add(IssueComment(msg)) props_path = os.path.join(self.base_path, '_lintreview.properties') # Close the file before trying to read. # There have been problems with reading properties while # the file handle is still open. with open(props_path, 'w+') as f: self.setup_properties(f) properties_filename = os.path.basename(f.name) command = self.create_command(properties_filename, files) output = docker.run('checkstyle', command, self.base_path) # Cleanup the generated properties file. os.remove(props_path) # Only one line is generally a config error. Replay the error # to the user. lines = output.strip().split('\n') if not lines[0].startswith('<'): msg = ("Running `checkstyle` failed with:\n" "```\n" "%s\n" "```\n" "Ensure your config file exists and is valid XML.") return self.problems.add(IssueComment(msg % (lines[0],))) # Remove the last line if it is not XML # Checkstyle outputs text after the XML if there are errors. if not lines[-1].strip().startswith('<'): lines = lines[0:-1] output = ''.join(lines) process_checkstyle(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with csslint. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) cmd = 'csslint' command = [cmd, '--format=compact'] if self.options.get('ignore'): command += ['--ignore=' + self.options.get('ignore')] command += files output = docker.run( 'nodejs', command, source_dir=self.base_path) self._process_output(output)
def process_files(self, files): command = ['foodcritic', '--no-progress'] # if no directory is set, assume the root path = self.options.get('path', '') path = docker.apply_base(path) command.append(path) output = docker.run('ruby2', command, self.base_path) if output[0] == '\n': log.debug('No foodcritic errors found.') return False for line in output.split("\n"): if len(line.strip()) == 0: return filename, line, error = self._parse_line(line) self.problems.add(filename, line, error)
def process_files(self, files): """ Run code checks with stylelint. """ log.debug('Processing %s files with %s', files, self.name) command = self._create_command() command += files output = docker.run( 'nodejs', command, source_dir=self.base_path) if 'SyntaxError' in output or 'ENOENT' in output: msg = ( u"Your configuration file resulted in the following error:\n" "```\n" "{}" "```\n" ) return self.problems.add(IssueComment(msg.format(output))) process_quickfix(self.problems, output.splitlines(), docker.strip_base)
def process_files(self, files): """ Run code checks with TSLint. """ log.debug('Processing %s files with %s', files, self.name) command = ['tslint', '--format', 'checkstyle'] # Add config file or default to recommended linters if self.options.get('config'): command += ['-c', docker.apply_base(self.options['config'])] if self.options.get('project'): command += ['--project', docker.apply_base(self.options['project'])] command += files output = docker.run( 'nodejs', command, source_dir=self.base_path) self._process_output(output, files)
def process_files(self, files): """ Run code checks with phpcs. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) command = self.create_command(files) output = docker.run( 'phpcs', command, source_dir=self.base_path) # Check for errors from PHPCS if output.startswith('ERROR'): msg = ('Your PHPCS configuration output the following error:\n' '```\n' '{}\n' '```') error = '\n'.join(output.split('\n')[0:1]) return self.problems.add(IssueComment(msg.format(error))) process_checkstyle(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with jsonlint. Only a single process is made for all files to save resources. Configuration is not supported at this time """ log.debug('Processing %s files with %s', files, self.name) command = ['jsonlint'] command += files output = docker.run( 'python2', command, source_dir=self.base_path) if not output: log.debug('No jsonlint errors found.') return False output = output.split("\n") process_quickfix(self.problems, output, docker.strip_base)
def process_files(self, files): """ Run code checks with sass-lint. Only a single process is made for all files to save resources. """ log.debug('Processing %s files with %s', files, self.name) command = ['sass-lint', '-f', 'checkstyle', '-v', '-q'] command += files if self.options.get('ignore'): command += ['--ignore ', self.options.get('ignore')] if self.options.get('config'): command += ['--config', docker.apply_base(self.options['config'])] output = docker.run( 'nodejs', command, source_dir=self.base_path) # sass-lint is very silly and outputs multiple xml documents. # One for each file... for line in output.split("\n"): process_checkstyle(self.problems, line, docker.strip_base)