summaryrefslogtreecommitdiffstats
path: root/gitlint/options.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2021-12-04 03:31:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2021-12-04 03:31:41 +0000
commit72b8c35be4293bd21de123854491c658c53af100 (patch)
tree735464cc081879561927a37650b1102beaa1f4f9 /gitlint/options.py
parentAdding upstream version 0.16.0. (diff)
downloadgitlint-upstream/0.17.0.tar.xz
gitlint-upstream/0.17.0.zip
Adding upstream version 0.17.0.upstream/0.17.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gitlint/options.py')
-rw-r--r--gitlint/options.py149
1 files changed, 0 insertions, 149 deletions
diff --git a/gitlint/options.py b/gitlint/options.py
deleted file mode 100644
index 9fdac8f..0000000
--- a/gitlint/options.py
+++ /dev/null
@@ -1,149 +0,0 @@
-from abc import abstractmethod
-import os
-import re
-
-from gitlint.exception import GitlintError
-
-
-def allow_none(func):
- """ Decorator that sets option value to None if the passed value is None, otherwise calls the regular set method """
-
- def wrapped(obj, value):
- if value is None:
- obj.value = None
- else:
- func(obj, value)
-
- return wrapped
-
-
-class RuleOptionError(GitlintError):
- pass
-
-
-class RuleOption:
- """ Base class representing a configurable part (i.e. option) of a rule (e.g. the max-length of the title-max-line
- rule).
- This class should not be used directly. Instead, use on the derived classes like StrOption, IntOption to set
- options of a particular type like int, str, etc.
- """
-
- def __init__(self, name, value, description):
- self.name = name
- self.description = description
- self.value = None
- self.set(value)
-
- @abstractmethod
- def set(self, value):
- """ Validates and sets the option's value """
- pass # pragma: no cover
-
- def __str__(self):
- return f"({self.name}: {self.value} ({self.description}))"
-
- def __eq__(self, other):
- return self.name == other.name and self.description == other.description and self.value == other.value
-
-
-class StrOption(RuleOption):
- @allow_none
- def set(self, value):
- self.value = str(value)
-
-
-class IntOption(RuleOption):
- def __init__(self, name, value, description, allow_negative=False):
- self.allow_negative = allow_negative
- super().__init__(name, value, description)
-
- def _raise_exception(self, value):
- if self.allow_negative:
- error_msg = f"Option '{self.name}' must be an integer (current value: '{value}')"
- else:
- error_msg = f"Option '{self.name}' must be a positive integer (current value: '{value}')"
- raise RuleOptionError(error_msg)
-
- @allow_none
- def set(self, value):
- try:
- self.value = int(value)
- except ValueError:
- self._raise_exception(value)
-
- if not self.allow_negative and self.value < 0:
- self._raise_exception(value)
-
-
-class BoolOption(RuleOption):
-
- # explicit choice to not annotate with @allow_none: Booleans must be False or True, they cannot be unset.
- def set(self, value):
- value = str(value).strip().lower()
- if value not in ['true', 'false']:
- raise RuleOptionError(f"Option '{self.name}' must be either 'true' or 'false'")
- self.value = value == 'true'
-
-
-class ListOption(RuleOption):
- """ Option that is either a given list or a comma-separated string that can be splitted into a list when being set.
- """
-
- @allow_none
- def set(self, value):
- if isinstance(value, list):
- the_list = value
- else:
- the_list = str(value).split(",")
-
- self.value = [str(item.strip()) for item in the_list if item.strip() != ""]
-
-
-class PathOption(RuleOption):
- """ Option that accepts either a directory or both a directory and a file. """
-
- def __init__(self, name, value, description, type="dir"):
- self.type = type
- super().__init__(name, value, description)
-
- @allow_none
- def set(self, value):
- value = str(value)
-
- error_msg = ""
-
- if self.type == 'dir':
- if not os.path.isdir(value):
- error_msg = f"Option {self.name} must be an existing directory (current value: '{value}')"
- elif self.type == 'file':
- if not os.path.isfile(value):
- error_msg = f"Option {self.name} must be an existing file (current value: '{value}')"
- elif self.type == 'both':
- if not os.path.isdir(value) and not os.path.isfile(value):
- error_msg = (f"Option {self.name} must be either an existing directory or file "
- f"(current value: '{value}')")
- else:
- error_msg = f"Option {self.name} type must be one of: 'file', 'dir', 'both' (current: '{self.type}')"
-
- if error_msg:
- raise RuleOptionError(error_msg)
-
- self.value = os.path.realpath(value)
-
-
-class RegexOption(RuleOption):
-
- @allow_none
- def set(self, value):
- try:
- self.value = re.compile(value, re.UNICODE)
- except (re.error, TypeError) as exc:
- raise RuleOptionError(f"Invalid regular expression: '{exc}'") from exc
-
- def __deepcopy__(self, _):
- # copy.deepcopy() - used in rules.py - doesn't support copying regex objects prior to Python 3.7
- # To work around this, we have to implement this __deepcopy__ magic method
- # Relevant SO thread:
- # https://stackoverflow.com/questions/6279305/typeerror-cannot-deepcopy-this-pattern-object
- value = None if self.value is None else self.value.pattern
- return RegexOption(self.name, value, self.description)