-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsettings.py
More file actions
134 lines (106 loc) · 4.32 KB
/
settings.py
File metadata and controls
134 lines (106 loc) · 4.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# -*- coding: utf-8 -*-
from __future__ import annotations
import dataclasses
import decimal
import inspect
import pathlib
from collections.abc import MutableMapping
from typing import Any
class MissingEnvironmentVariable(Exception):
pass
class InvalidAnnotationType(Exception):
pass
def path_below(path_str: str | pathlib.Path) -> pathlib.Path:
path = pathlib.Path(path_str).resolve()
if not (path.exists() and path.is_file()):
raise ValueError('Path does not exist')
if path.suffix != '.json':
raise ValueError('The file is not a JSON file.')
return path
def str_to_bool(value: str) -> bool:
return value.lower() in ('1', 'true', 'yes')
# sdfs
# pylint: disable=invalid-name, too-many-instance-attributes
@dataclasses.dataclass
class Config:
"""This object defines the environment variables"""
GITHUB_REPOSITORY: str
COVERAGE_PATH: pathlib.Path
GITHUB_TOKEN: str = dataclasses.field(repr=False)
GITHUB_PR_NUMBER: int | None = None
# Branch to run the action on (alternate to get PR number if not provided)
# Example Organisation:branch-name (Company:sample-branch) or User:branch-name (user:sample-branch)
GITHUB_REF: str | None = None
GITHUB_BASE_REF: str = 'main'
SUBPROJECT_ID: str | None = None
MINIMUM_GREEN: decimal.Decimal = decimal.Decimal('100')
MINIMUM_ORANGE: decimal.Decimal = decimal.Decimal('70')
SKIP_COVERAGE: bool = False
ANNOTATE_MISSING_LINES: bool = False
ANNOTATION_TYPE: str = 'warning'
ANNOTATIONS_OUTPUT_PATH: pathlib.Path | None = None
MAX_FILES_IN_COMMENT: int = 25
COMPLETE_PROJECT_REPORT: bool = False
COVERAGE_REPORT_URL: str | None = None
# Only for debugging, not exposed in the action
DEBUG: bool = False
def __post_init__(self) -> None:
if self.GITHUB_PR_NUMBER is None and self.GITHUB_REF is None:
raise ValueError('Either GITHUB_PR_NUMBER or GITHUB_REF must be provided')
# Clean methods
@classmethod
def clean_minimum_green(cls, value: str) -> decimal.Decimal:
return decimal.Decimal(value)
@classmethod
def clean_minimum_orange(cls, value: str) -> decimal.Decimal:
return decimal.Decimal(value)
@classmethod
def clean_annotate_missing_lines(cls, value: str) -> bool:
return str_to_bool(value)
@classmethod
def clean_skip_coverage(cls, value: str) -> bool:
return str_to_bool(value)
@classmethod
def clean_complete_project_report(cls, value: str) -> bool:
return str_to_bool(value)
@classmethod
def clean_debug(cls, value: str) -> bool:
return str_to_bool(value)
@classmethod
def clean_annotation_type(cls, value: str) -> str:
if value not in {'notice', 'warning', 'error'}:
raise InvalidAnnotationType(
f'The annotation type {value} is not valid. Please choose from notice, warning or error'
)
return value
@classmethod
def clean_github_pr_number(cls, value: str) -> int:
return int(value)
@classmethod
def clean_coverage_path(cls, value: str) -> pathlib.Path:
return path_below(value)
@classmethod
def clean_annotations_output_path(cls, value: str) -> pathlib.Path:
return pathlib.Path(value)
# We need to type environ as a MutableMapping because that's what
# os.environ is, and `dict[str, str]` is not enough
@classmethod
def from_environ(cls, environ: MutableMapping[str, str]) -> Config:
possible_variables = list(inspect.signature(cls).parameters)
config: dict[str, Any] = {k: v for k, v in environ.items() if k in possible_variables}
for key, value in list(config.items()):
if func := getattr(cls, f'clean_{key.lower()}', None):
try:
config[key] = func(value)
except ValueError as exc:
raise ValueError(f'{key}: {exc!s}') from exc
try:
config_obj = cls(**config)
except TypeError as e:
missing = {
name
for name, param in inspect.signature(cls).parameters.items()
if param.default is inspect.Parameter.empty
} - set(environ)
raise MissingEnvironmentVariable(f" missing environment variable(s): {', '.join(missing)}") from e
return config_obj