13 from tempfile
import TemporaryDirectory
15 from .ApiConfig
import ApiConfig, Runner
16 from .CliOptions
import CliOptions
21 Setup temp_dir using the diff or current MR
23 :ivar temp_dir: Temporary directory location for storing MR changes.
24 :ivar allowlist: Allow list from JSON
25 :ivar api_config: ApiConfig
26 :ivar cli_options: CliOptions object
29 def __init__(self, cli_options: CliOptions, api_config: ApiConfig):
33 :param cli_options: CliOptions object to get allow list from
34 :param api_config: API configuration for the CI
36 self.temp_dir: TemporaryDirectory[str] | TemporaryDirectory[bytes] \
37 = TemporaryDirectory()
38 self.allowlist: dict[str, list[str]] = cli_options.allowlist
39 self.api_config: ApiConfig = api_config
40 self.cli_options: CliOptions = cli_options
44 Clean the created temp dir
46 self.temp_dir.cleanup()
50 Check if the path is allow listed
52 The function used fnmatch to check if the path is in allow list or not.
54 :param path: path to check
55 :return: True if the path is in allow list, False otherwise
57 for pattern
in self.allowlist.
get(
'exclude', []):
58 if fnmatch.fnmatchcase(path, pattern):
64 Populate temp dir using the gitlab API `merge_requests`
66 :return: temp dir path
69 context = ssl.create_default_context()
70 context.check_hostname =
False
71 context.verify_mode = ssl.CERT_NONE
73 if self.api_config.running_on == Runner.GITLAB:
74 headers = {
'Private-Token': self.api_config.api_token}
78 f
"{self.api_config.api_url}/projects/"
79 f
"{self.api_config.project_id}/merge_requests/"
80 f
"{self.api_config.mr_iid}/changes"
82 if self.cli_options.differential
and self.cli_options.tags != (
'',
''):
83 tags = self.cli_options.tags
85 f
"{self.api_config.api_url}/projects/"
86 f
"{self.api_config.project_id}/repository/compare?"
87 f
"from={tags[0]}&to={tags[1]}"
90 elif self.api_config.running_on == Runner.GITHUB:
92 "Authorization": f
"Bearer {self.api_config.api_token}",
93 "X-GitHub-Api-Version":
"2022-11-28",
94 "Accept":
"application/vnd.github+json"
99 f
"{self.api_config.api_url}/repos/"
100 f
"{self.api_config.github_repo_slug}/pulls/"
101 f
"{self.api_config.github_pull_request}/files"
103 if self.cli_options.differential
and self.cli_options.tags != (
'',
''):
104 tags = self.cli_options.tags
106 f
"{self.api_config.api_url}/repos/"
107 f
"{self.api_config.github_repo_slug}/compare/"
108 f
"{tags[0]}...{tags[1]}"
113 "https://api.github.com/repos/"
114 f
"{self.api_config.travis_repo_slug}/pulls/"
115 f
"{self.api_config.travis_pull_request}/files"
118 path_key =
"filename"
122 raise ValueError(
"API request URL could not be constructed. Check ApiConfig and runner type.")
124 req = urllib.request.Request(api_req_url, headers=headers)
126 with urllib.request.urlopen(req, context=context)
as response:
127 change_response = response.read()
128 except Exception
as e:
129 print(f
"Unable to get URL {api_req_url}")
132 change_response = json.loads(change_response)
133 if self.api_config.running_on == Runner.GITLAB:
134 if self.cli_options.differential
and self.cli_options.tags != (
'',
''):
135 changes = change_response.get(
'diffs', [])
137 changes = change_response.get(
'changes', [])
138 elif self.api_config.running_on == Runner.GITHUB:
139 if self.cli_options.differential
and self.cli_options.tags != (
'',
''):
140 changes = change_response.get(
'files', [])
142 changes = change_response
144 changes = change_response
146 for change
in changes:
147 if path_key
in change
and change_key
in change:
148 file_path_in_repo = change[path_key]
150 full_temp_file_path = os.path.join(self.temp_dir.name, file_path_in_repo)
151 target_dir = os.path.dirname(full_temp_file_path)
152 if target_dir
and not os.path.exists(target_dir):
153 os.makedirs(name=target_dir, exist_ok=
True)
156 with open(file=full_temp_file_path, mode=
'w+', encoding=
'UTF-8')
as f:
157 f.write(change[change_key])
159 print(f
"Error writing file {full_temp_file_path}: {e}")
162 return self.temp_dir.name
bool __is_excluded_path(self, str path)
def __init__(self, CliOptions cli_options, ApiConfig api_config)