class PerlCriticBear: """ Check the code with perlcritic. This will run perlcritic over each of the files seperately. """ LANGUAGES = {'Perl'} REQUIREMENTS = { DistributionRequirement(apt_get='perl'), DistributionRequirement(apt_get='libperl-critic-perl') } AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Syntax', 'Formatting', 'Code Simplification'} @staticmethod def create_arguments(filename, file, config_file, perlcritic_profile: str = ''): """ :param perlcritic_profile: Location of the perlcriticrc config file. """ args = ('--no-color', ) if perlcritic_profile: args += ('--profile', perlcritic_profile) return args + (filename, )
class GhcModBear: # pragma nt: no cover """ Syntax checking with ``ghc`` for Haskell files. See <https://hackage.haskell.org/package/ghc-mod> for more information! """ LANGUAGES = {'Haskell'} REQUIREMENTS = { AnyOneOfRequirements( [CabalRequirement('ghc-mod', '5.6.0.0'), DistributionRequirement('ghc-mod') ] ), } AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' ASCIINEMA_URL = 'https://asciinema.org/a/98873' CAN_DETECT = {'Syntax'} @staticmethod def create_arguments(filename, file, config_file): # -b '. ' is the argument given for ghc-mod for seperation of messages return '-b', '. ', 'check', filename
class CheckstyleBear: """ Check Java code for possible style, semantic and design issues. For more information, consult <http://checkstyle.sourceforge.net/checks.html>. """ LANGUAGES = {'Java'} REQUIREMENTS = {DistributionRequirement(apt_get='default-jre')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Formatting', 'Smell'} def setup_dependencies(self): type(self).checkstyle_jar_file = self.download_cached_file( 'http://sourceforge.net/projects/checkstyle/files/checkstyle/6.19' '/checkstyle-6.19-all.jar', 'checkstyle-6.19.jar') def create_arguments( self, filename, file, config_file, checkstyle_configs: known_checkstyle_or_path = 'google', use_spaces: bool = True, indent_size: int = 2, ): """ :param checkstyle_configs: A file containing configs to use in ``checkstyle``. It can also have the special values: - google - Google's Java style. More info at <http://checkstyle.sourceforge.net/style_configs.html>. - sun - Sun's Java style. These are the same as the default Eclipse checks. More info at <http://checkstyle.sourceforge.net/style_configs.html>. - android-check-easy - The easy Android configs provided by the android-check eclipse plugin. More info at <https://github.com/noveogroup/android-check>. - android-check-hard - The hard Android confis provided by the android-check eclipse plugin. More info at <https://github.com/noveogroup/android-check>. - geosoft - The Java style followed by GeoSoft. More info at <http://geosoft.no/development/javastyle.html> """ check_invalid_configuration( checkstyle_configs, use_spaces, indent_size) if checkstyle_configs in ('google', 'sun'): # Checkstyle included these two rulesets since version 6.2 # Locate the file as an absolute resource into the checkstyle jar checkstyle_configs = '/%s_checks.xml' % checkstyle_configs elif checkstyle_configs in _online_styles: checkstyle_configs = self.download_cached_file( _online_styles[checkstyle_configs], checkstyle_configs + '.xml') return ('-jar', self.checkstyle_jar_file, '-c', checkstyle_configs, filename)
class CPPCheckBear: """ Report possible security weaknesses for C/C++. For more information, consult <https://github.com/danmar/cppcheck>. """ LANGUAGES = {'C', 'C++'} REQUIREMENTS = {DistributionRequirement(apt_get='cppcheck')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Security', 'Unused Code', 'Unreachable Code', 'Smell'} @staticmethod def create_arguments(filename, file, config_file, enable: typed_list(str)=[]): """ :param enable: Choose specific issues to report. Issues that can be reported are: all, warning, style, performance, portability, information, unusedFunction, missingInclude """ args = ('--template={line}:{severity}:{id}:{message}',) if enable: args += ('--enable=' + ','.join(enable),) return args + (filename,)
class VerilogLintBear: """ Analyze Verilog code using ``verilator`` and checks for all lint related and code style related warning messages. It supports the synthesis subset of Verilog, plus initial statements, proper blocking/non-blocking assignments, functions, tasks. It also warns about unused code when a specified signal is never sinked, and unoptimized code due to some construct, with which the optimization of the specified signal or block is disabled. This is done using the ``--lint-only`` command. For more information visit <http://www.veripool.org/projects/verilator/wiki/Manual-verilator>. """ LANGUAGES = {'Verilog'} REQUIREMENTS = { DistributionRequirement( apt_get='verilator', brew=None, dnf='verilator', portage=None, yum='verilator', zypper='verilator', ), } AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' ASCIINEMA_URL = 'https://asciinema.org/a/45275' CAN_DETECT = {'Formatting', 'Code Simplification', 'Syntax', 'Unused Code'} @staticmethod def create_arguments(filename, file, config_file): return '--lint-only', filename
class ScalaLintBear: """ Check Scala code for codestyle, but also semantical problems, e.g. cyclomatic complexity. """ LANGUAGES = {'Scala'} REQUIREMENTS = {DistributionRequirement(apt_get='default-jre')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' INCLUDE_LOCAL_FILES = {'scalastyle.jar', 'scalalint_config.xml'} CAN_DETECT = {'Formatting', 'Complexity'} def setup_dependencies(self): type(self).jar = self.download_cached_file( 'https://oss.sonatype.org/content/repositories/releases/org/' 'scalastyle/scalastyle_2.10/0.8.0/scalastyle_2.10-0.8.0-batch.jar', 'scalastyle.jar') @staticmethod def create_arguments(filename, file, config_file, scalalint_config: str = scalastyle_config_file): """ :param scalalint_config: Path to a custom configuration file. """ return ('-jar', ScalaLintBear.jar, filename, '--config', scalalint_config)
class DartLintBear: """ Checks the code with ``dart-linter``. This bear expects dart commands to be on your ``PATH``. Please ensure /path/to/dart-sdk/bin is in your ``PATH``. """ LANGUAGES = {'Dart'} REQUIREMENTS = {DistributionRequirement(brew='dart')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Syntax', 'Formatting'} @staticmethod def create_arguments( filename, file, config_file, use_spaces: bool = True, indent_size: int = 2, ): # use_spaces must be True and indent_size must be 2 because # dartanalyzer only supports these settings # see https://github.com/dart-lang/dart_style/issues/261 if (indent_size != 2 or not use_spaces): raise ValueError('DartLintBear only supports `use_spaces=True` ' 'and `indent_size=2`') return filename,
class PHPMessDetectorBear: """ The bear takes a given PHP source code base and looks for several potential problems within that source. These problems can be things like: - Possible bugs - Suboptimal code - Overcomplicated expressions - Unused parameters, methods, properties """ LANGUAGES = {'PHP'} REQUIREMENTS = {DistributionRequirement(apt_get='phpmd')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = { 'Formatting', 'Complexity', 'Unused Code', 'Redundancy', 'Variable Misuse' } SEE_MORE = 'https://phpmd.org/about.html' @staticmethod def create_arguments(filename, file, config_file, phpmd_rulesets: typed_list(str)): """ :param phpmd_rulesets: A list of rulesets to use for analysis. Available rulesets: cleancode, codesize, controversial, design, naming, unusedcode. """ return filename, 'text', ','.join(phpmd_rulesets)
class LicenseCheckBear: """ Attempts to check the given file for a license, by searching the start of the file for text belonging to various licenses. For Ubuntu/Debian users, the ``licensecheck_lines`` option has to be used in accordance with the ``licensecheck_tail`` option. """ LANGUAGES = {'All'} REQUIREMENTS = { DistributionRequirement(apt_get='devscripts', dnf='licensecheck') } AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'License'} @staticmethod def create_arguments(filename, file, config_file, licensecheck_lines: int = 60, licensecheck_tail: int = 5000): """ :param licensecheck_lines: Specify how many lines of the file header should be parsed for license information. Set to 0 to parse the whole file (and ignore ``licensecheck_tail``). :param licensecheck_tail: Specify how many bytes to parse at end of file. Set to 0 to disable parsing from end of file. """ return ('--lines', str(licensecheck_lines), '--tail', str(licensecheck_tail), filename)
class ShellCheckBear: # pragma nt: no cover """ Check bash/shell scripts for syntactical problems (with understandable messages), semantical problems as well as subtle caveats and pitfalls. A gallery of bad code that can be detected is available at <https://github.com/koalaman/shellcheck/blob/master/README.md>. """ LANGUAGES = {'sh', 'bash', 'ksh', 'dash'} REQUIREMENTS = {AnyOneOfRequirements( [CabalRequirement('ShellCheck', '0.4.1'), DistributionRequirement('shellcheck') ] ), } AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Syntax', 'Security', 'Undefined Element', 'Unused Code'} @staticmethod def create_arguments(filename, file, config_file, shell: str = 'sh', shellcheck_ignore: list = None, ): """ :param shell: Target shell being used. :param shellcheck_ignore: List of linting rules that should be ignored. """ args = ('--f', 'gcc', '-s', shell, filename) if shellcheck_ignore: args += ('-e', ','.join(shellcheck_ignore)) return args
class XMLBear: """ Checks the code with ``xmllint``. See http://xmlsoft.org/xmllint.html """ LANGUAGES = {'XML'} REQUIREMENTS = { DistributionRequirement( 'libxml2', apt_get='libxml2-utils', portage='dev-libs/libxml2', ), } AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Formatting', 'Syntax'} _output_regex = re.compile( r'.*:(?P<line>\d+):.*(?P<severity>error|warning)\s?: ' r'(?P<message>.*)\n.*\n.*') @staticmethod def create_arguments(filename, file, config_file, xml_schema: path='', xml_dtd: path_or_url=''): """ :param xml_schema: ``W3C XML Schema`` file used for validation. :param xml_dtd: ``Document type Definition (DTD)`` file or url used for validation. """ args = (filename,) if xml_schema: args += ('-schema', xml_schema) if xml_dtd: args += ('-dtdvalid', xml_dtd) return args def process_output(self, output, filename, file): stdout, stderr = output if stdout: # Return issues from stderr and stdout if stdout is not empty return itertools.chain( self.process_output_regex( stderr, filename, file, output_regex=self._output_regex), self.process_output_corrected( stdout, filename, file, diff_severity=RESULT_SEVERITY.INFO, result_message='XML can be formatted better.')) else: # Return issues from stderr if stdout is empty return self.process_output_regex( stderr, filename, file, output_regex=self._output_regex)
class HaskellLintBear: """ Check Haskell code for possible problems. This bear can propose patches for using alternative functions, simplifying code and removing redundancies. See <http://community.haskell.org/~ndm/darcs/hlint/hlint.htm> for more information. """ LANGUAGES = {'Haskell'} REQUIREMENTS = { AnyOneOfRequirements([ CabalRequirement(package='hlint', version='1.9.27'), DistributionRequirement(apt_get='hlint'), ], ), } AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Duplication'} CAN_FIX = {'Unused Code', 'Code Simplification'} severity_map = { 'Error': RESULT_SEVERITY.MAJOR, 'Warning': RESULT_SEVERITY.NORMAL, 'Suggestion': RESULT_SEVERITY.INFO } @staticmethod def create_arguments(filename, file, config_file): return '--json', filename def process_output(self, output, filename, file): output = json.loads(output) for issue in output: diff = Diff(file) from_lines = issue['from'].splitlines() to_lines = issue['to'].splitlines() assert len(from_lines) == len(to_lines) for other_lines in range(1, len(from_lines)): assert from_lines[other_lines] == to_lines[other_lines] line_nr = issue['startLine'] line_to_change = file[line_nr - 1] newline = line_to_change.replace(from_lines[0], to_lines[0]) diff.change_line(line_nr, line_to_change, newline) yield Result.from_values( origin=self, message=issue['hint'], file=filename, severity=self.severity_map[issue['severity']], line=issue['startLine'], column=issue['startColumn'], end_line=issue['endLine'], end_column=issue['endColumn'], diffs={filename: diff})
class CPPCheckBear: """ Report possible security weaknesses for C/C++. For more information, consult <https://github.com/danmar/cppcheck>. """ LANGUAGES = {'C', 'CPP'} REQUIREMENTS = {DistributionRequirement('cppcheck')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Security', 'Unused Code', 'Unreachable Code', 'Smell'} def create_arguments( self, config_file, enable: typed_list(str) = [], language: str = None, ): """ :param enable: Choose specific issues to report. Issues that can be reported are: all, warning, style, performance, portability, information, unusedFunction, missingInclude :param language: Choose specific language for linting. Language can be either c or c++ """ args = ('--template={file}:{line}:{severity}:{id}:{message}', ) files = tuple(self.file_dict.keys()) if enable: args += ('--enable=' + ','.join(enable), ) if language is not None: try: lang = Language[language] if isinstance(lang, Language.CPP): args += ('--language=c++', ) elif isinstance(lang, Language.C): args += ('--language=c', ) else: logging.error('Language can be either c or c++') return except Exception: logging.error('Language can be either c or c++') return return args + files
class RubySyntaxBear: """ Checks the code with ``ruby -wc`` on each file separately. """ LANGUAGES = {'Ruby'} REQUIREMENTS = {DistributionRequirement(apt_get='ruby')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Syntax'} @staticmethod def create_arguments(filename, file, config_file): return '-wc', filename
class PHPLintBear: """ Checks the code with ``php -l``. This runs it on each file separately. """ LANGUAGES = {'PHP'} REQUIREMENTS = {DistributionRequirement(apt_get='php-cli')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Syntax'} @staticmethod def create_arguments(filename, file, config_file): return ('-l', '-n', '-d', 'display_errors=On', '-d', 'log_errors=Off', filename)
class CSharpLintBear: """ Checks C# code for syntactical correctness using the ``mcs`` compiler. """ LANGUAGES = {'C#'} REQUIREMENTS = {DistributionRequirement(apt_get='mono-mcs')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Syntax'} @staticmethod def create_arguments(filename, file, config_file): return filename,
class LuaLintBear: """ Check Lua code for possible semantic problems, like unused code. Read more at <https://github.com/mpeterv/luacheck>. """ LANGUAGES = {'Lua'} REQUIREMENTS = {DistributionRequirement(apt_get='luarocks')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Unreachable Code', 'Unused Code', 'Variable Misuse'} @staticmethod def create_arguments(filename, file, config_file): return '-', '--formatter=plain', '--ranges', '--codes'
class RLintBear: """ Checks the code with ``lintr``. """ LANGUAGES = {'R'} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} REQUIREMENTS = { RscriptRequirement('lintr'), DistributionRequirement(apt_get='r-base', version='>=3.1.1') } LICENSE = 'AGPL-3.0' CAN_DETECT = {'Syntax', 'Formatting'} @staticmethod def create_arguments(filename, file, config_file): return ('-e', 'library(lintr)', '-e', 'lintr::lint("' + escape(filename, '\\"') + '")')
class LatexLintBear: # pragma nt: no cover """ Checks the code with ``chktex``. """ LANGUAGES = {'Tex'} REQUIREMENTS = {DistributionRequirement('chktex', zypper='texlive-chktex')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Syntax', 'Formatting'} @staticmethod def create_arguments(filename, file, config_file): return ( '--format', '%k %n in {0} line %l: %m!n'.format(filename), filename, )
class CSecurityBear: """ Report possible security weaknesses for C/C++. For more information, consult <http://www.dwheeler.com/flawfinder/>. """ LANGUAGES = {'C', 'C++'} REQUIREMENTS = {DistributionRequirement('flawfinder')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' ASCIINEMA_URL = 'https://asciinema.org/a/7z8ol9mpsgtuo1096c6jk8hi6' CAN_DETECT = {'Security', 'Memory Leak', 'Code Simplification'} @staticmethod def create_arguments(filename, file, config_file): return '--columns', '--dataonly', '--quiet', '--singleline', filename
class VHDLLintBear: # pragma nt: no cover """ Check VHDL code for common codestyle problems. Rules include: * Signals, variables, ports, types, subtypes, etc. must be lowercase. * Constants and generics must be uppercase. * Entities, architectures and packages must be "mixedcase" (may be 100% uppercase, but not 100% lowercase). * Ports must be suffixed using _i, _o or _io denoting its kind. * Labels must be placed in a separated line. Exception: component instantiation. * End statements must be documented indicating what are finishing. * Buffer ports are forbidden. * VHDL constructions of the "entity xxxx is" and similars must be in one line. You can't put "entity xxxxx" in one line and "is" in another. * No more than one VHDL construction is allowed in one line of code. See <http://fpgalibre.sourceforge.net/ingles.html#tp46> for more information. """ LANGUAGES = {'VHDL'} REQUIREMENTS = {DistributionRequirement('perl')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Formatting'} @classmethod def check_prerequisites(cls): if which('perl') is None: return 'perl is not installed.' elif which('bakalint.pl') is None: return ('bakalint is missing. Download it from ' '<http://fpgalibre.sourceforge.net/ingles.html#tp46> and ' 'put it into your PATH.') else: return True @staticmethod def create_arguments(filename, file, config_file): return which('bakalint.pl'), '--input', filename
class RLintBear: # pragma nt: no cover """ Checks the code with ``lintr``. """ LANGUAGES = {'R'} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} REQUIREMENTS = { RscriptRequirement('lintr', version='>=1.0.2'), DistributionRequirement(apt_get='r-base', version='>=3.1.1') } LICENSE = 'AGPL-3.0' ASCIINEMA_URL = 'https://asciinema.org/a/178910' CAN_DETECT = {'Syntax', 'Formatting'} SEE_MORE = 'https://github.com/jimhester/lintr' @staticmethod def create_arguments(filename, file, config_file): return ('-e', 'library(lintr)', '-e', 'lintr::lint("' + escape(filename, '\\"') + '")')
class JuliaLintBear: """ Provide analysis related to common bugs and potential issues in Julia like dead code, undefined variable usage, duplicate keys in dicts, incorrect ADT usage, wrongfully using ellipsis, and much more. See <https://lintjl.readthedocs.org/en/stable/> for more information on the analysis provided. """ LANGUAGES = {'Julia'} REQUIREMENTS = {DistributionRequirement(apt_get='julia')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = {'Unused Code', 'Syntax', 'Redundancy', 'Duplication', 'Unreachable Code', 'Security', 'Formatting'} @staticmethod def create_arguments(filename, file, config_file): lintcode = ('import Lint.lintfile; display(lintfile("' + escape(filename, '"\\') + '"))') return '-e', lintcode
class GNUIndentBear: """ This bear checks and corrects spacing and indentation via the well known Indent utility. C++ support is considered experimental. """ LANGUAGES = {'C', 'C++'} REQUIREMENTS = {DistributionRequirement('indent')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_FIX = {'Formatting'} @staticmethod @deprecate_settings(indent_size='tab_width') def create_arguments( filename, file, config_file, max_line_length: int = 79, use_spaces: bool = True, blank_lines_after_declarations: bool = False, blank_lines_after_procedures: bool = False, blank_lines_after_commas: bool = False, braces_on_if_line: bool = False, braces_on_func_def_line: bool = False, cuddle_else: bool = False, while_and_brace_on_same_line: bool = False, case_indentation: int = 0, space_before_semicolon_after_empty_loop: bool = True, delete_optional_blank_lines: bool = True, declaration_indent: int = 0, brace_indent: int = 2, gnu_style: bool = False, k_and_r_style: bool = False, linux_style: bool = False, indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH, indent_cli_options: str = '', ): """ :param max_line_length: Maximum number of characters for a line. When set to 0, infinite line length is allowed. :param use_spaces: True if spaces are to be used, else tabs. :param blank_lines_after_declarations: Forces blank lines after the declarations. Example: If ``blank_lines_after_declarations = True`` then:: int a; return ...; changes to:: int a; return ...; :param blank_lines_after_procedures: Force blank lines after procedure bodies. :param blank_lines_after_commas: Forces newline after comma in declaration. Example: If ``blank_lines_after_commas = True`` then:: int a, b; changes to:: int a, b; :param braces_on_if_line: Puts the brace ``{`` on same line with if. Example: If ``braces_on_if_line = True`` then:: if (x > 0) { changes to:: if (x > 0) { :param braces_on_func_def_line: Puts the brace `{` on same line with the function declaration. :param cuddle_else: Cuddle else and preceding ``}``. Example: If ``cuddle_else = True`` then:: if (...) { .... } else { changes to:: if (...) { .... } else { :param while_and_brace_on_same_line: Cuddles while of ``do {} while``; and preceding ``}``. :param case_indentation: Specifies the number of spaces by which ``case`` in the ``switch`` are indented. :param space_before_semicolon_after_empty_loop: Forces a blank before the semicolon ``;`` on one-line ``for`` and ``while`` statements. :param delete_optional_blank_lines: Deletes blank lines that are not needed. An example of needed blank line, is the blank line following a declaration when ``blank_line_after_declaration=True``. :param declaration_indent: Forces variables names to be aligned in column ``n`` with ``n = declaration_indent`` in declaration. Example: If ``declaration_indent = 8`` then:: int a; float b; changes to:: int a; float b; :param brace_indent: Specifies the number of spaces by which braces are indented. Its default value is 2. :param gnu_style: Uses GNU coding style. :param k_and_r_style: Uses Kernighan & Ritchie coding style. :param linux_style: Uses Linux coding style. :param indent_size: Number of spaces per indentation level. :param indent_cli_options: Any command line options the indent binary understands. They will be simply passed through. """ # The limit is set to an arbitrary high value if not max_line_length: max_line_length = sys.maxsize indent_options = ( '--no-tabs' if use_spaces else '--use-tabs', '--line-length', str(max_line_length), '--indent-level', str(indent_size), '--tab-size', str(indent_size), ) indent_options += (('--cuddle-do-while', ) if while_and_brace_on_same_line else ('--dont-cuddle-do-while', )) indent_options += (('--swallow-optional-blank-lines', ) if delete_optional_blank_lines else ('-nsob', )) indent_options += (('--blank-lines-after-declarations', ) if blank_lines_after_declarations else ('-nbad', )) indent_options += (('--blank-lines-after-commas', ) if blank_lines_after_commas else ('-nbc', )) indent_options += (('--blank-lines-after-procedures', ) if blank_lines_after_procedures else ('-nbap', )) indent_options += (('-di' + str(declaration_indent), ) if declaration_indent != 0 else ()) indent_options += (('--case-indentation' + str(case_indentation), ) if case_indentation != 0 else ()) indent_options += (('--space-special-semicolon', ) if space_before_semicolon_after_empty_loop else ('-nss', )) indent_options += ('--brace-indent' + str(brace_indent), ) indent_options += (('--braces-on-func-def-line', ) if braces_on_func_def_line else ('-blf', )) indent_options += ((('-ce', ) if cuddle_else else ('-nce', )) + ('-br', )) if braces_on_if_line else ('-bl', ) indent_style_option = () indent_style_option += ('--gnu-style', ) if gnu_style else () indent_style_option += (('--k-and-r-style', ) if k_and_r_style and indent_style_option is () else ()) indent_style_option += (('--linux-style', ) if linux_style and indent_style_option is () else ()) # If a style is chosen the other configs aren't passed to `indent` return (indent_style_option if indent_style_option is not () else indent_options) + tuple(shlex.split(indent_cli_options))
class PHPCodeSnifferBear: """ Ensures that your PHP, JavaScript or CSS code remains clean and consistent. See <https://github.com/squizlabs/PHP_CodeSniffer> for more information. """ LANGUAGES = {'PHP', 'JavaScript', 'CSS'} REQUIREMENTS = { AnyOneOfRequirements([ DistributionRequirement( apt_get='php-codesniffer', zypper='php-pear-php_codesniffer', ), ComposerRequirement('squizlabs/php_codesniffer'), ], ), } AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_DETECT = { 'Formatting', 'Syntax', 'Documentation', 'Code Simplification' } ASCIINEMA_URL = 'https://asciinema.org/a/efawv96vdalck73tc3hwcabov' @staticmethod def create_arguments(filename, file, config_file): return '--report=emacs', '--standard=' + config_file, filename @staticmethod def generate_config(filename, file, max_line_length: int = 79, line_ending_character: str = '\\n', indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH, use_spaces: bool = True, allow_multiple_statements_per_line: bool = False, force_lower_case_keywords: bool = True, force_lower_case_constants: bool = True, blank_line_after_namespace_declaration: bool = True, check_use_blocks: bool = True, check_class_declaration: bool = True, check_property_declaration: bool = True, force_scope_modifier_on_method: bool = True, function_declaration_argument_spacing: int = 1, allow_multiline_function_declaration: bool = True): """ :param max_line_length: Maximum number of characters for a line. :param line_ending_character: Checks that end of line characters correspond to the one provided. :param indent_size: Number of spaces per indentation level. :param use_spaces: True if spaces are to be used instead of tabs. :param allow_multiple_statements_per_line: Allows having multiple statements on one line. :param force_lower_case_keyword: Checks that ``PHP`` keywords are lowercase. :param force_lower_case_constant: Checks that all uses of ``true``, ``false`` and ``null`` are lowercase. :param blank_line_after_namespace_declaration: Ensures that there is a blank line after a namespace declaration. :param check_use_blocks: Ensures that there is one blank line after a ``use`` block, that there is only one use block per line, and that all ``use`` declaration are done after namespaces declaration. :param check_class_declaration: Ensures that ``extends`` and ``implements`` keywords are declared on the same line as the class name, that the opening brace for a class is on the next line, and that the closing brace for a class is on the next line after the body. Allows splitting implements list accross multiple lines. :param check_property_declaration: Ensures that visibility is declared on all properties, that the ``var`` keyword is not used to declare a property, that there is not more that one property declared on a line, that properties are not prefixed with an underscore. :param force_scope_modifier_on_method: Verifies that class methods have scope modifiers. :param function_declaration_argument_spacing: Number of spaces between arguments in function declaration. :param allow_multiline_function_declaration: Allows argument lists to be split accross multiple lines correctly indented. """ rules_map = { 'Generic.WhiteSpace.DisallowTabIndent': use_spaces, 'Generic.Formatting.DisallowMultipleStatements': not allow_multiple_statements_per_line, 'Generic.PHP.LowerCaseKeyword': force_lower_case_keywords, 'Generic.PHP.LowerCaseConstant': force_lower_case_constants, 'PSR2.Namespaces.UseDeclaration': check_use_blocks, 'PSR2.Namespaces.NamespaceDeclaration': blank_line_after_namespace_declaration, 'PSR2.Classes.ClassDeclaration': check_class_declaration, 'PSR2.Classes.PropertyDeclaration': check_property_declaration, 'Squiz.Scope.MethodScope': force_scope_modifier_on_method, 'Squiz.Functions.MultiLineFunctionDeclaration': allow_multiline_function_declaration } rules = '' for k, v in rules_map.items(): rules += '<rule ref="{}"/>\n'.format(k) if v else '' configs = '''<?xml version="1.0"?> <ruleset name="Custom Standard"> <description>A custom coding standard</description> <!-- Include the whole PSR-1 standard --> <rule ref="PSR1"/> <rule ref="Generic.Files.LineLength"> <properties> <property name="lineLimit" value="{max_line_length}"/> <property name="absoluteLineLimit" value="{absolute_line_length}"/> </properties> </rule> <rule ref="Generic.Files.LineEndings"> <properties> <property name="eolChar" value="{line_ending_character}"/> </properties> </rule> <rule ref="Generic.WhiteSpace.ScopeIndent"> <properties> <property name="ignoreIndentationTokens" type="array" value="T_COMMENT,T_DOC_COMMENT_OPEN_TAG"/> </properties> <properties> <property name="indent" value="{indent_size}"/> </properties> <properties> <property name="exact" value="true"/> </properties> </rule> {some_rules} <rule ref="Squiz.WhiteSpace.ScopeKeywordSpacing"/> <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing"> <properties> <property name="equalsSpacing" value="{function_declaration_argument_spacing}"/> </properties> </rule> <rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint"> <severity>0</severity> </rule> </ruleset> '''.format(max_line_length=max_line_length, absolute_line_length=0, line_ending_character=line_ending_character, indent_size=indent_size, some_rules=rules, function_declaration_argument_spacing=( function_declaration_argument_spacing)) return configs
class TailorBear: """ Analyze Swift code and check for code style related warning messages. For more information on the analysis visit <https://tailor.sh/> """ LANGUAGES = {'Swift'} REQUIREMENT = {DistributionRequirement(brew='tailor')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' ASCIINEMA_URL = 'https://asciinema.org/a/45666' CAN_DETECT = {'Formatting'} severity_map = { 'warning': RESULT_SEVERITY.NORMAL, 'error': RESULT_SEVERITY.MAJOR } def process_output(self, output, filename, file): output = json.loads(output) for item in output['files'][0]['violations']: column = (item['location']['column'] if 'column' in item['location'].keys() else None) yield Result.from_values( origin='{} ({})'.format(self.name, item['rule']), message=item['message'], file=filename, line=item['location']['line'], column=column, severity=self.severity_map[item['severity']]) @staticmethod def create_arguments(filename, file, config_file, max_line_length: int = 79, max_class_length: int = 0, max_closure_length: int = 0, max_file_length: int = 0, max_function_length: int = 0, max_name_length: int = 0, max_struct_length: int = 0, min_name_length: int = 1, tailor_config: path = ''): """ Bear configuration arguments. Using '0' will disable the check. :param max_line_length: maximum number of characters in a Line <0-999>. :param max_class_length: maximum number of lines in a Class <0-999>. :param max_closure_length: maximum number of lines in a Closure <0-999>. :param max_file_length: maximum number of lines in a File <0-999>. :param max_function_length: maximum number of lines in a Function <0-999>. :param max_name_length: maximum length of Identifier name <0-999>. :param max_struct_length: maximum number od lines in a Struct <0-999>. :param min_name_length: minimum number of characters in Identifier name <1-999>. :param tailor_config: path to Tailor configuration file. """ args = ('--format=json', '--max-line-length', str(max_line_length), '--max-class-length', str(max_class_length), '--max-closure-length', str(max_closure_length), '--max-file-length', str(max_file_length), '--max-function-length', str(max_function_length), '--max-name-length', str(max_name_length), '--max-struct-length', str(max_struct_length), '--min-name-length', str(min_name_length)) if tailor_config: args += ('--config=' + tailor_config, ) return args + (filename, )
class ArtisticStyleBear: """ Artistic Style is a source code indenter, formatter, and beautifier for the C, C++, C++/CLI, Objective-C, C# and Java programming languages. """ LANGUAGES = {'C', 'C++', 'Objective-C', 'C#', 'Java'} REQUIREMENTS = {DistributionRequirement(apt_get='astyle', dnf='astyle')} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} LICENSE = 'AGPL-3.0' CAN_FIX = {'Formatting'} SEE_MORE = 'http://astyle.sourceforge.net/astyle.html' @staticmethod def create_arguments( filename, file, config_file, bracket_style: str = '', use_spaces: bool = None, indent_size: int = 4, require_braces_at_namespace: bool = True, require_braces_at_class: bool = True, require_braces_at_inline: bool = True, require_braces_at_extern: bool = False, allow_indent_classes: bool = True, allow_indent_modifiers: bool = True, allow_indent_switches: bool = True, allow_indent_cases: bool = True, allow_indent_namespaces: bool = False, allow_indent_labels: bool = True, allow_indent_preproc_block: bool = True, allow_indent_preproc_definition: bool = True, allow_indent_preproc_conditionals: bool = True, allow_indent_column_one_comments: bool = True, allow_pad_header_blocks: bool = True, allow_pad_operators: bool = True, allow_pad_parenthesis: bool = False, allow_pad_parenthesis_out: bool = False, allow_pad_parenthesis_in: bool = False, prohibit_empty_lines_in_func: bool = False, break_closing_braces: bool = False, break_elseifs: bool = False, break_one_line_headers: bool = False, require_braces_at_one_line_conditionals: bool = False, prohibit_braces_from_one_line_conditionals: bool = False, prohibit_comment_prefix: bool = True): """ :param bracket_style: Defines the brace style to use. Possible values are ``allman, java, kr, stroustrup, whitesmith, vtk, banner, gnu, linux, horstmann, google, mozilla, pico and lisp.`` For example: Allman style uses braces that are broken from the previous block. If set to ``allman``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: Java style uses braces that are attached to the end of the last line of the previous block. If set to ``java``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: Kernighan & Ritchie style uses linux braces. Opening braces are broken from ``namespaces``, ``classes`` and ``function`` definitions. The braces are attached to everything else, including arrays, structs, enums, and statements within a function. If set to ``kr``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: Stroustrup style uses linux braces with closing headers broken from closing braces. Opening braces are broken from function definitions only. The opening braces are attached to everything else, including ``namespaces``, ``classes``, ``arrays``, ``structs``, enums, and statements within a function. If set to ``stroustrup``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: Whitesmith style uses broken, indented braces. Switch blocks and class blocks are indented to prevent a 'hanging indent' with the following case statements and C++ class modifiers (``public``, ``private``, ``protected``). If set to ``whitesmith``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: VTK (Visualization Toolkit) style uses broken, indented braces, except for the opening brace. Switch blocks are indented to prevent a 'hanging indent' with following case statements. If set to ``vtk``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: Banner style uses attached, indented braces. Switch blocks and class blocks are indented to prevent a 'hanging indent' with following case statements and C++ class modifiers (``public``, ``private``, ``protected``). If set to ``banner``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: GNU style uses broken braces and indented blocks. Extra indentation is added to blocks within a function only. Other braces and blocks are broken, but NOT indented. This style frequently is used with an indent of 2 spaces. If set to ``gnu``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: Linux style uses linux braces. Opening braces are broken from namespace, class, and function definitions. The braces are attached to everything else, including ``arrays``, ``structs``, ``enums``, and statements within a function. The minimum conditional indent is one-half indent. If you want a different minimum conditional indent, use the K&R style instead. This style works best with a large indent. It frequently is used with an indent of 8 spaces. If set to ``linux``, prefer:: int Foo(bool isBar) { if (isFoo) { bar(); return 1; } else return 0; } For example: Horstmann style uses broken braces and run-in statements. ``Switches`` are indented to allow a run-in to the opening ``switch`` block. This style frequently is used with an indent of 3 spaces. If set to ``horstmann``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: Google style uses attached braces and indented class access modifiers. This is not actually a unique brace style, but is Java style with a non-brace variation. This style frequently is used with an indent of 2 spaces. If set to ``google``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: Mozilla style uses linux braces. Opening braces are broken from ``classes``, ``structs``, ``enums``, and ``function`` definitions. The braces are attached to everything else, including ``namespaces``, ``arrays``, and ``statements`` within a ``function``. This style frequently is used with an indent of 2 spaces. If set to ``mozilla``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: Pico style uses broken braces and run-in statements with attached closing braces. The closing brace is attached to the last line in the block. ``Switches`` are indented to allow a run-in to the opening ``switch`` block. This style frequently is used with an indent of 2 spaces. If set to ``pico``, prefer:: int Foo(bool isBar) { if (isBar) { bar(); return 1; } else return 0; } For example: Lisp style uses attached opening and closing braces. The closing brace is attached to the last line in the block. If set to ``lisp``, prefer:: int Foo(bool isBar) { if (isBar) { bar() return 1; } else return 0; } :param use_spaces: In the following examples, ``q`` space is indicated with a ``.`` (dot), a tab is indicated by a > (greater than). For example: If ``None``, the default option of 4 spaces will be used as below:: void Foo() { ....if (isBar1 ............&& isBar2) ........bar(); } For example: If set to ``True``, spaces will be used for indentation. For example: If set to ``False``, tabs will be used for indentation, and spaces for continuation line alignment as below:: void Foo() { > if (isBar1 > ........&& isBar2) > > bar(); } :param indent_size: Number of spaces per indentation level. For example: If ``use_spaces`` is ``True`` and ``indent_size`` is ``3``, prefer:: void Foo() { ...if (isBar1 .........&& isBar2) ......bar(); } :param require_braces_at_namespace: Attach braces to a namespace statement. This is done regardless of the brace style being used. For example: If set to ``True``, prefer:: namespace FooName { ... } :param require_braces_at_class: Attach braces to a class statement. This is done regardless of the brace style being used. For example: If set to ``True``, prefer:: class FooClass { ... }; :param require_braces_at_inline: Attach braces to class and struct inline function definitions. This option has precedence for all styles except ``Horstmann`` and ``Pico`` (run-in styles). It is effective for C++ files only. For example: If set to ``True``, prefer:: class FooClass { void Foo() { ... } }; :param require_braces_at_extern: Attach braces to a braced extern "C" statement. This is done regardless of the brace style being used. This option is effective for C++ files only. For example: If set to ``True``, prefer:: #ifdef __cplusplus extern "C" { #endif :param allow_indent_classes: Indent ``class`` and ``struct`` blocks so that the entire block is indented. The ``struct`` blocks are indented only if an access modifier, ``public:``, ``protected:`` or ``private:``, is declared somewhere in the ``struct``. This option is effective for C++ files only. For example: If set to ``True``, prefer this:: class Foo { public: Foo(); virtual ~Foo(); }; over this:: class Foo { public: Foo(); virtual ~Foo(); }; :param allow_indent_modifiers: Indent ``class`` and ``struct`` access modifiers, ``public:``, ``protected:`` and ``private:``, one half indent. The rest of the class is not indented. This option is effective for C++ files only. For example: If set to ``True``, prefer this:: class Foo { public: Foo(); virtual ~Foo(); }; over this:: class Foo { public: Foo(); virtual ~Foo(); }; :param allow_indent_switches: Indent ``switch`` blocks so that the ``case X:`` statements are indented in the switch block. The entire case block is indented. For example: If set to ``True``, prefer this:: switch (foo) { case 1: a += 1; break; case 2: { a += 2; break; } } over this:: switch (foo) { case 1: a += 1; break; case 2: { a += 2; break; } } :param allow_indent_cases: Indent ``case X:`` blocks from the ``case X:`` headers. Case statements not enclosed in blocks are NOT indented. For example: If set to ``True``, prefer this:: switch (foo) { case 1: a += 1; break; case 2: { a += 2; break; } } over this:: switch (foo) { case 1: a += 1; break; case 2: { a += 2; break; } } :param allow_indent_namespaces: Add extra indentation to namespace blocks. This option has no effect on Java files. For example: If set to ``True``, prefer this:: namespace foospace { class Foo { public: Foo(); virtual ~Foo(); }; } over this:: namespace foospace { class Foo { public: Foo(); virtual ~Foo(); }; } :param allow_indent_labels: Add extra indentation to labels so they appear 1 indent less than the current indentation, rather than being flushed to the left (the default). For example: If set to ``True``, prefer this:: void Foo() { while (isFoo) { if (isFoo) goto error; ... error: ... } } over this:: void Foo() { while (isFoo) { if (isFoo) goto error; ... error: ... } } :param allow_indent_preproc_block: Indent preprocessor blocks at brace level zero and immediately within a namespace. There are restrictions on what will be indented. Blocks within methods, classes, arrays, etc., will not be indented. Blocks containing braces or multi-line define statements will not be indented. Without this option the preprocessor block is not indented. For example: If set to ``True``, prefer this:: #ifdef _WIN32 #include <windows.h> #ifndef NO_EXPORT #define EXPORT #endif #endif over this:: #ifdef _WIN32 #include <windows.h> #ifndef NO_EXPORT #define EXPORT #endif #endif :param allow_indent_preproc_definition: Indent multi-line preprocessor definitions ending with a backslash. Should be used with ``convert_tabs_to_spaces`` for proper results. Does a pretty good job, but cannot perform miracles in obfuscated preprocessor definitions. Without this option the preprocessor statements remain unchanged. For example: If set to ``True``, prefer this:: #define Is_Bar(arg,a,b) \ (Is_Foo((arg), (a)) \ || Is_Foo((arg), (b))) over this:: #define Is_Bar(arg,a,b) \ (Is_Foo((arg), (a)) \ || Is_Foo((arg), (b))) :param allow_indent_preproc_conditionals: Indent preprocessor conditional statements to the same level as the source code. For example: If set to ``True``, prefer this:: isFoo = true; #ifdef UNICODE text = wideBuff; #else text = buff; #endif over this:: isFoo = true; #ifdef UNICODE text = wideBuff; #else text = buff; #endif :param allow_indent_column_one_comments: Indent C++ comments beginning in column one. By default C++ comments beginning in column one are assumed to be commented-out code and not indented. This option will allow the comments to be indented with the code. For example: If set to ``True``, prefer this:: void Foo()\n" { // comment if (isFoo) bar(); } over this:: void Foo()\n" { // comment if (isFoo) bar(); } :param allow_pad_header_blocks: Pad empty lines around header blocks (e.g. ``if``, ``for``, ``while``...). For example: If set to ``True``, prefer this:: isFoo = true; if (isFoo) { bar(); } else { anotherBar(); } isBar = false; over this:: isFoo = true; if (isFoo) { bar(); } else { anotherBar(); } isBar = false; :param allow_pad_operators: Insert space padding around operators. This will also pad commas. For example: If set to ``True``, prefer this:: if (foo == 2) a = bar((b - c) * a, d--); over this:: if (foo==2) a=bar((b-c)*a,d--); :param allow_pad_parenthesis: Insert space padding around parenthesis on both the outside and the inside. For example: If set to ``True``, prefer this:: if ( isFoo ( ( a+2 ), b ) ) bar ( a, b ); over this:: if (isFoo((a+2), b)) bar(a, b); :param allow_pad_parenthesis_out: Insert space padding around parenthesis on the outside only. Parenthesis that are empty will not be padded. For example: If set to ``True``, prefer this:: if (isFoo ( (a+2), b) ) bar (a, b); over this:: if (isFoo((a+2), b)) bar(a, b); :param allow_pad_parenthesis_in: Insert space padding around parenthesis on the inside only. For example: If set to ``True``, prefer this:: if ( isFoo( ( a+2 ), b ) ) bar( a, b ); over this:: if (isFoo((a+2), b)) bar(a, b); :param prohibit_empty_lines_in_func: Delete empty lines within a function or method. Empty lines outside of functions or methods are NOT deleted. For example: If set to ``True``, prefer this:: void Foo() { foo1 = 1; foo2 = 2; } over this:: void Foo() { foo1 = 1; foo2 = 2; } :param break_closing_braces: When used with some specific ``bracket_style``, this breaks closing headers (e.g. ``else``, ``catch``, ...) from their immediately preceding closing braces. Closing header braces are always broken with the other styles. For example: If set to ``True``, prefer this:: void Foo(bool isFoo) { if (isFoo) { bar(); } else { anotherBar(); } } over this:: void Foo(bool isFoo) { if (isFoo) { bar(); } else { anotherBar(); } } :param break_elseifs: Break ``else if`` header combinations into separate lines. For example: If set to ``True``, prefer this:: if (isFoo) { bar(); } else if (isFoo1()) { bar1(); } else if (isFoo2()) { bar2(); } over this:: if (isFoo) { bar(); } else if (isFoo1()) { bar1(); } else if (isFoo2()) { bar2; } :param break_one_line_headers: Break one line headers (e.g. ``if``, ``while``, ``else``, ...) from a statement residing on the same line. If the statement is enclosed in braces, the braces will be formatted according to the requested brace style. For example: If set to ``True``, prefer this:: void Foo(bool isFoo) { if (isFoo1) bar1(); if (isFoo2) { bar2(); } } over this:: void Foo(bool isFoo) { if (isFoo1) bar1(); if (isFoo2) { bar2(); } } :param require_braces_at_one_line_conditionals: Add braces to unbraced one line conditional statements (e.g. ``if``, ``for``, ``while``...). The statement must be on a single line. The braces will be added according to the requested brace style. For example: If set to ``True``, prefer this:: if (isFoo) { isFoo = false; } over this:: if (isFoo) isFoo = false; :param prohibit_braces_from_one_line_conditionals: Remove braces from conditional statements (e.g. ``if``, ``for``, ``while``...). The statement must be a single statement on a single line. For example: If set to ``True``, prefer this:: if (isFoo) isFoo = false; over this:: if (isFoo) { isFoo = false; } :param prohibit_comment_prefix: Remove the preceding '*' in a multi-line comment that begins a line. A trailing '*', if present, is also removed. Text that is less than one indent is indented to one indent. Text greater than one indent is not changed. Multi-line comments that begin a line, but without the preceding '*', are indented to one indent for consistency. This can slightly modify the indentation of commented out blocks of code. Lines containing all '*' are left unchanged. Extra spacing is removed from the comment close '*/'. For example: If set to ``True``, prefer this:: /* comment line 1 comment line 2 */ over this:: /* * comment line 1 * comment line 2 */ """ rules_map = { '--attach-namespaces': require_braces_at_namespace, '--attach-classes': require_braces_at_class, '--attach-inlines': require_braces_at_inline, '--attach-extern-c': require_braces_at_extern, '--indent-classes': allow_indent_classes, '--indent-modifiers': allow_indent_modifiers, '--indent-switches': allow_indent_switches, '--indent-cases': allow_indent_cases, '--indent-namespaces': allow_indent_namespaces, '--indent-labels': allow_indent_labels, '--indent-preproc-block': allow_indent_preproc_block, '--indent-preproc-define': allow_indent_preproc_definition, '--indent-preproc-cond': allow_indent_preproc_conditionals, '--indent-col1-comments': allow_indent_column_one_comments, '--break-blocks': allow_pad_header_blocks, '--pad-oper': allow_pad_operators, '--pad-paren': allow_pad_parenthesis, '--pad-paren-out': allow_pad_parenthesis_out, '--pad-paren-in': allow_pad_parenthesis_in, '--delete-empty-lines': prohibit_empty_lines_in_func, '--break-closing-brackets': break_closing_braces, '--break-elseifs': break_elseifs, '--break-one-line-headers': break_one_line_headers, '--add-brackets': require_braces_at_one_line_conditionals, '--remove-brackets': prohibit_braces_from_one_line_conditionals, '--remove-comment-prefix': prohibit_comment_prefix } args = ['--suffix=none', '--dry-run'] if bracket_style: args.append('--style=' + bracket_style) if use_spaces is True: args.append('-s' + str(indent_size)) elif use_spaces is False: args.append('-t' + str(indent_size)) args += (k for k, v in rules_map.items() if v) return args
class FormatRBear: """ Check and correct formatting of R Code using known formatR utility. """ LANGUAGES = {'R'} AUTHORS = {'The coala developers'} AUTHORS_EMAILS = {'*****@*****.**'} REQUIREMENTS = { AnyOneOfRequirements( [DistributionRequirement( apt_get='r-cran-formatr', zypper='R-formatR', ), RscriptRequirement('formatR'), ] ) } LICENSE = 'AGPL-3.0' ASCIINEMA_URL = 'https://asciinema.org/a/0y0oxtak18v492jdyfqwpw1n4' CAN_FIX = {'Formatting'} @staticmethod @deprecate_settings(indent_size='tab_width') def create_arguments(filename, file, config_file, r_keep_comments: bool = True, r_keep_blank_lines: bool = True, r_braces_on_next_line: bool = None, r_use_arrows: bool = None, indent_size: int = SpacingHelper.DEFAULT_TAB_WIDTH, r_max_expression_length: int = 0, ): """ :param r_keep_comments: Determines whether comments are kept or not. :param r_keep_blank_lines: Determines whether blank lines are kept or not. :param r_braces_on_next_line: Determines whether a brace should be placed on the next line. Example: If ``True``:: if (...) { changes to:: if (...) { If ``False`` the brace is placed on the same line. :param r_use_arrows: Determines whether the assignment operator ``=`` should be replaced by an arrow ``<-`` or not. Example: If ``True``, ``x = 1`` changes to ``x <- 1``. :param indent_size: Number of spaces per indentation level. :param r_max_expression_length: Maximum number of characters for an expression. Example: If ``20`` then:: 1 + 1 + 1 + 1 + 1 + 1 + 1 changes to:: 1 + 1 + 1 + 1 + 1 + 1 + 1 """ options = {'source="' + escape(filename, '"\\') + '"', 'blank=' + _map_to_r_bool(r_keep_blank_lines), 'comment=' + _map_to_r_bool(r_keep_comments), 'indent=' + str(indent_size)} if r_max_expression_length: options.add('width.cutoff=' + str(r_max_expression_length)) if r_braces_on_next_line is not None: options.add('brace.newline=' + _map_to_r_bool(r_braces_on_next_line)) if r_use_arrows is not None: options.add('arrow=' + _map_to_r_bool(r_use_arrows)) rcode = 'library(formatR);formatR::tidy_source({})'.format( ','.join(options)) return '-e', rcode