coala/cEPs

cEP-0023: Separation of metadata of bears

yukiisbored opened this issue · 2 comments

Most Python code we've written for bears are simple metadata that instructs coala on what to run, how to read the output, what to pass to the command, etc.

We can reduce the overall work, difficulty when writing, and size of coala Bears if it was in it's simplified form containing only necessary complication without the mess of having to copy paste boilerplate code.

Bears that require special needs can have it's Python code separated from the meta-data.

Here's an example of how it may look like:

Directory tree of the new bear:

|
|_ GoVetBear/
|  |_  meta.toml
|
|_ SpaceInconsistencyBear/
|  |_ meta.toml
|  |_ bear.py
|

What the metadata may look like:

[identity]
name = "GoVetBear"
description = """\
              Analyze Go code and raise suspicious constructs, such as printf calls \
              whose arguments do not correctly match the format string, useless \
              assignments, common mistakes about boolean operations, unreachable code, \
              etc.\
              """
languages = ["Go"]
authors = ["The coala developers"]
authors_email = ["coala-devel@googlegroups.com"]
license = "AGPL-3.0"
can_detect = ["Unused code", "Smell", "Unreachable Code"]

[[requirements]]
type = "AnyOneOf"

    [[requirements.child]]
    type = "binary"
    name = "go"

    [[requirements.child]]
    type = "apt"
    name = "golang"

[[requirements]]
type = "GoRequirement"
package = "golang.org/cmd/vet"
flag = "-u"

[bear]
executable = "go"
use_stdout = false
use_stderr = true
output_format = "regex"
output_regex = ".+:(?P<line>\d+): (?P<message>.*)"
[identity]
name = "SpaceConsistencyBear"
description = """\
              Check and correct spacing for all textual data. This includes usage of \
              tabs vs. spaces, trailing whitespace and (missing) newlines before \
              the end of the file.\
              """
languages = ["All"]
authors = ["The coala developers"]
authors_email = ["coala-devel@googlegroups.com"]
license = "AGPL-3.0"
can_detect = ["Formatting"]

[[params]]
name = "use_spaces"
description = "True if spaces are to be used instead of tabs."
type = "bool"

[[params]]
name = "allow_trailing_whitespace"
description = "Whether to allow trailing whitespace or not."
type = "bool"
default = false

[[params]]
name = "indent_size"
description = "Number of spaces per indentation level"
type = "int"
default = 8

[[params]]
name = "enforce_newline_at_EOF"
description = "Whether to enforce a newline at the end of file"
type = "bool"
default = true

[bear]
executable = "bear.py"
local = true

How local bears will look like:

#!/usr/bin/env python3

from coalib.bearlib import deprecate_settings
from coalib.bearlib.spacing.SpacingHelper import SpacingHelper
from coalib.results.Diff import Diff
from coalib.results.Result import Result

def main():
    spacing_helper = SpacingHelper(indent_size)
    result_texts = []
    additional_info_texts = []

    for line_number, line in enumerate(file, start=1):
        replacement = line

        if enforce_newline_at_EOF:
            # Since every line contains at the end at least one \n, only
            # the last line could potentially not have one. So we don't
            # need to check whether the current line_number is the last
            # one.
            if replacement[-1] != '\n':
                replacement += '\n'
                result_texts.append('No newline at EOF.')
                additional_info_texts.append(
                    "A trailing newline character ('\\n') is missing from "
                    'your file. '
                    '<http://stackoverflow.com/a/5813359/3212182> gives '
                    'more information about why you might need one.')

            if not allow_trailing_whitespace:
                replacement = replacement.rstrip(' \t\n') + '\n'
                if replacement != line.rstrip('\n') + '\n':
                    result_texts.append('Trailing whitespaces.')
                    additional_info_texts.append(
                        'Your source code contains trailing whitespaces. '
                        'Those usually have no meaning. Please consider '
                        'removing them.')

            if use_spaces:
                pre_replacement = replacement
                replacement = replacement.expandtabs(indent_size)
                if replacement != pre_replacement:
                    result_texts.append('Tabs used instead of spaces.')
        else:
            pre_replacement = replacement
            replacement = spacing_helper.replace_spaces_with_tabs(
                replacement)
            if replacement != pre_replacement:
                result_texts.append('Spaces used instead of tabs.')

        if len(result_texts) > 0:
            diff = Diff(file)
            diff.change_line(line_number, line, replacement)
            inconsistencies = ''.join('\n- ' + string
                                          for string in result_texts)
            yield Result.from_values(
                self,
                'Line contains following spacing inconsistencies:'
                + inconsistencies,
                diffs={filename: diff},
                file=filename,
                line=line_number,
                additional_info='\n\n'.join(additional_info_texts))
            result_texts = []
            additional_info_texts = []

if __name__ == '__main__':
    main()

Obviously the above Python code will not run but it shows the point that coala shouldn't be a Python exclusive tool. It should enable other organizations/projects that doesn't use Python to use coala. This might be the first step into the world of non-Python exclusive local bears. Enabling organizations that uses other languages to write their own bears and It also enables an easier way to declare local linters that are used exclusively (like the various paid/commercial code safety checkers) to the project/organization.

I'd like to point out, I'm using TOML for the bear metadata language. It may be a good choice for writing bears.

https://github.com/toml-lang/toml

Please i would like to work on this issue
Can i have hints on how to approach the problem