How to use the nitpick.plugins.base.NitpickPlugin function in nitpick

To help you get started, we’ve selected a few nitpick examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github andreoliwa / nitpick / src / nitpick / style.py View on Github external
def rebuild_dynamic_schema(self, data: JsonDict = None) -> None:
        """Rebuild the dynamic Marshmallow schema when needed, adding new fields that were found on the style."""
        new_files_found = OrderedDict()  # type: Dict[str, fields.Field]

        if data is None:
            # Data is empty; so this is the first time the dynamic class is being rebuilt.
            # Loop on classes with predetermined names, and add fields for them on the dynamic validation schema.
            # E.g.: setup.cfg, pre-commit, pyproject.toml: files whose names we already know at this point.
            for subclass in NitpickPlugin.fixed_name_classes:
                new_files_found.update(self.file_field_pair(subclass.file_name, subclass))
        else:
            handled_tags = {}  # type: Dict[str, Type[NitpickPlugin]]

            # Data was provided; search it to find new dynamic files to add to the validation schema).
            # E.g.: JSON files that were configured on some TOML style file.
            for subclass in NitpickPlugin.dynamic_name_classes:
                for tag in subclass.identify_tags:
                    # A tag can only be handled by a single subclass.
                    # If more than one class handle a tag, the latest one will be the handler.
                    handled_tags[tag] = subclass

                jmex = subclass.get_compiled_jmespath_file_names()
                for configured_file_name in search_dict(jmex, data, []):
                    new_files_found.update(self.file_field_pair(configured_file_name, subclass))
github andreoliwa / nitpick / src / nitpick / plugins / setup_cfg.py View on Github external
"""Checker for the `setup.cfg ` config file."""
from configparser import ConfigParser
from io import StringIO
from typing import Any, Dict, List, Optional, Set, Tuple, Type

import dictdiffer

from nitpick.plugins import hookimpl
from nitpick.plugins.base import NitpickPlugin
from nitpick.typedefs import JsonDict, YieldFlake8Error


class SetupCfgPlugin(NitpickPlugin):
    """Checker for the `setup.cfg `_ config file.

    Example: :ref:`flake8 configuration `.
    """

    file_name = "setup.cfg"
    error_base_number = 320
    COMMA_SEPARATED_VALUES = "comma_separated_values"

    expected_sections = set()  # type: Set[str]
    missing_sections = set()  # type: Set[str]

    def __init__(self, config: JsonDict, file_name: str = None) -> None:
        super().__init__(config, file_name)
        self.comma_separated_values = set(self.nitpick_file_dict.get(self.COMMA_SEPARATED_VALUES, []))  # type: Set[str]
github andreoliwa / nitpick / src / nitpick / plugins / pre_commit.py View on Github external
"""Get all hooks from a YAML string. Split the string in hooks and copy the repo info for each."""
        yaml = YAMLFormat(string=str_or_yaml).as_list if isinstance(str_or_yaml, str) else str_or_yaml
        hooks = []
        for repo in yaml:
            for index, hook in enumerate(repo.get(KEY_HOOKS, [])):
                repo_data_only = repo.copy()
                repo_data_only.pop(KEY_HOOKS)
                hook_data_only = search_dict("{}[{}]".format(KEY_HOOKS, index), repo, {})
                repo_data_only.update({KEY_HOOKS: [hook_data_only]})
                hooks.append(
                    PreCommitHook(repo.get(KEY_REPO), hook[KEY_ID], YAMLFormat(data=[repo_data_only])).key_value_pair
                )
        return OrderedDict(hooks)


class PreCommitPlugin(NitpickPlugin):
    """Checker for the `.pre-commit-config.yaml `_ file.

    Example: :ref:`the default pre-commit hooks `.
    """

    file_name = ".pre-commit-config.yaml"
    error_base_number = 330

    actual_yaml = None  # type: YAMLFormat
    actual_hooks = OrderedDict()  # type: OrderedDict[str, PreCommitHook]
    actual_hooks_by_key = {}  # type: Dict[str, int]
    actual_hooks_by_index = []  # type: List[str]

    def suggest_initial_contents(self) -> str:
        """Suggest the initial content for this missing file."""
        original = dict(self.file_dict).copy()
github andreoliwa / nitpick / src / nitpick / app.py View on Github external
# pylint: disable=import-outside-toplevel
        from nitpick.config import Config  # pylint: disable=redefined-outer-name
        from nitpick.plugins.base import NitpickPlugin

        app = cls()
        cls._current_app = app
        app.offline = offline

        try:
            app.root_dir = app.find_root_dir()
            app.cache_dir = app.clear_cache_dir()

            app.main_python_file = app.find_main_python_file()
            app.config = Config()
            app.plugin_manager = app.load_plugins()
            NitpickPlugin.load_fixed_dynamic_classes()
        except (NoRootDir, NoPythonFile) as err:
            app.init_errors.append(err)

        return app
github andreoliwa / nitpick / src / nitpick / plugins / pyproject_toml.py View on Github external
"""Checker for `pyproject.toml `_."""
from typing import Optional, Set, Type

from nitpick.app import NitpickApp
from nitpick.plugins import hookimpl
from nitpick.plugins.base import NitpickPlugin
from nitpick.typedefs import JsonDict, YieldFlake8Error


class PyProjectTomlPlugin(NitpickPlugin):
    """Checker for `pyproject.toml `_.

    See also `PEP 518 `_.

    Example: :ref:`the Python 3.7 default `.
    There are many other examples in :ref:`defaults`.
    """

    file_name = "pyproject.toml"
    error_base_number = 310

    def check_rules(self) -> YieldFlake8Error:
        """Check missing key/value pairs in pyproject.toml."""
        if NitpickApp.current().config.pyproject_toml:
            comparison = NitpickApp.current().config.pyproject_toml.compare_with_flatten(self.file_dict)
            yield from self.warn_missing_different(comparison)
github andreoliwa / nitpick / src / nitpick / style.py View on Github external
def rebuild_dynamic_schema(self, data: JsonDict = None) -> None:
        """Rebuild the dynamic Marshmallow schema when needed, adding new fields that were found on the style."""
        new_files_found = OrderedDict()  # type: Dict[str, fields.Field]

        if data is None:
            # Data is empty; so this is the first time the dynamic class is being rebuilt.
            # Loop on classes with predetermined names, and add fields for them on the dynamic validation schema.
            # E.g.: setup.cfg, pre-commit, pyproject.toml: files whose names we already know at this point.
            for subclass in NitpickPlugin.fixed_name_classes:
                new_files_found.update(self.file_field_pair(subclass.file_name, subclass))
        else:
            handled_tags = {}  # type: Dict[str, Type[NitpickPlugin]]

            # Data was provided; search it to find new dynamic files to add to the validation schema).
            # E.g.: JSON files that were configured on some TOML style file.
            for subclass in NitpickPlugin.dynamic_name_classes:
                for tag in subclass.identify_tags:
                    # A tag can only be handled by a single subclass.
                    # If more than one class handle a tag, the latest one will be the handler.
                    handled_tags[tag] = subclass

                jmex = subclass.get_compiled_jmespath_file_names()
                for configured_file_name in search_dict(jmex, data, []):
                    new_files_found.update(self.file_field_pair(configured_file_name, subclass))

            self._find_subclasses(data, handled_tags, new_files_found)

        # Only recreate the schema if new fields were found.
        if new_files_found:
            self._dynamic_schema_class = type("DynamicStyleSchema", (self._dynamic_schema_class,), new_files_found)
github andreoliwa / nitpick / src / nitpick / plugins / text.py View on Github external
class TextItemSchema(Schema):
    """Validation schema for the object inside ``contains``."""

    error_messages = {"unknown": help_message("Unknown configuration", TEXT_FILE_RTFD_PAGE)}
    line = fields.NonEmptyString()


class TextSchema(Schema):
    """Validation schema for the text file TOML configuration."""

    error_messages = {"unknown": help_message("Unknown configuration", TEXT_FILE_RTFD_PAGE)}
    contains = fields.List(fields.Nested(TextItemSchema))


class TextPlugin(NitpickPlugin):
    """Checker for text files.

    To check if ``some.txt`` file contains the lines ``abc`` and ``def`` (in any order):

    .. code-block:: toml

        [["some.txt".contains]]
        line = "abc"

        [["some.txt".contains]]
        line = "def"
    """

    error_base_number = 350
    identify_tags = {"plain-text"}
    validation_schema = TextSchema
github andreoliwa / nitpick / src / nitpick / plugins / json.py View on Github external
from nitpick.schemas import BaseNitpickSchema
from nitpick.typedefs import JsonDict, YieldFlake8Error

KEY_CONTAINS_KEYS = "contains_keys"
KEY_CONTAINS_JSON = "contains_json"
LOGGER = logging.getLogger(__name__)


class JSONFileSchema(BaseNitpickSchema):
    """Validation schema for any JSON file added to the style."""

    contains_keys = fields.List(fields.NonEmptyString)
    contains_json = fields.Dict(fields.NonEmptyString, fields.JSONString)


class JSONPlugin(NitpickPlugin):
    """Checker for any JSON file.

    Add the configurations for the file name you wish to check.
    Example: :ref:`the default config for package.json `.
    """

    error_base_number = 340

    validation_schema = JSONFileSchema
    identify_tags = {"json"}

    SOME_VALUE_PLACEHOLDER = ""

    def check_rules(self) -> YieldFlake8Error:
        """Check missing keys and JSON content."""
        yield from self._check_contained_keys()