Coverage for src/types/gitlab.py: 67.57%
74 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-21 21:33 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-21 21:33 +0000
1#!/usr/bin/env python3
3# Standard libraries
4from os.path import join
5from typing import List, NamedTuple
7# Modules libraries
8from gitlab.v4.objects import (
9 GroupRunner,
10 ProjectRunner,
11)
13# MigrationEntities class
14class MigrationEntities:
16 # Members
17 cache_entities: List[str] = []
18 cache_keys: List[str] = []
19 cache_removers: List[str] = []
20 cache_templates: List[str] = []
22 # Entity
23 class Entity(NamedTuple):
25 # Variables
26 name: str
27 group_globs: List[str] = []
28 project_directories: List[str] = []
29 project_files: List[str] = []
31 # Remover
32 class Remover(Entity):
33 pass
35 # Template
36 class Template(Entity):
37 pass
39 # Defaults
40 @staticmethod
41 def defaults() -> List[str]:
43 # Return default exclusions
44 return [
45 MigrationEntities.MEMBERS.name,
46 ]
48 # Get
49 @staticmethod
50 def get(key: str) -> Entity:
52 # Get feature object
53 feature = getattr(MigrationEntities, key)
54 assert isinstance(feature, MigrationEntities.Entity)
55 return feature
57 # Keys
58 @staticmethod
59 def keys() -> List[str]:
61 # Evaluate keys
62 if MigrationEntities.cache_keys:
63 return MigrationEntities.cache_keys
65 # Evaluate keys
66 MigrationEntities.cache_keys = [
67 key for key in MigrationEntities.__dict__
68 if isinstance(getattr(MigrationEntities, key), MigrationEntities.Entity)
69 ]
70 return MigrationEntities.cache_keys
72 # Entities
73 @staticmethod
74 def entities() -> List[str]:
76 # Evaluate entities
77 if MigrationEntities.cache_entities:
78 return MigrationEntities.cache_entities
80 # Evaluate entities
81 MigrationEntities.cache_entities = [
82 MigrationEntities.get(key).name for key in MigrationEntities.__dict__
83 if isinstance(getattr(MigrationEntities, key), MigrationEntities.Entity) and
84 not isinstance(getattr(MigrationEntities, key), MigrationEntities.Remover) and
85 not isinstance(getattr(MigrationEntities, key), MigrationEntities.Template)
86 ]
87 return MigrationEntities.cache_entities
89 # Removers
90 @staticmethod
91 def removers() -> List[str]:
93 # Evaluate removers
94 if MigrationEntities.cache_removers:
95 return MigrationEntities.cache_removers
97 # Evaluate removers
98 MigrationEntities.cache_removers = [
99 MigrationEntities.get(key).name for key in MigrationEntities.__dict__
100 if isinstance(getattr(MigrationEntities, key), MigrationEntities.Remover)
101 ]
102 return MigrationEntities.cache_removers
104 # Templates
105 @staticmethod
106 def templates() -> List[str]:
108 # Evaluate templates
109 if MigrationEntities.cache_templates:
110 return MigrationEntities.cache_templates
112 # Evaluate templates
113 MigrationEntities.cache_templates = [
114 MigrationEntities.get(key).name for key in MigrationEntities.__dict__
115 if isinstance(getattr(MigrationEntities, key), MigrationEntities.Template)
116 ]
117 return MigrationEntities.cache_templates
119 # Entity: Members
120 MEMBERS = Entity(
121 name='Members',
122 group_globs=[
123 join('tree', 'groups', '*', 'members.ndjson'),
124 ],
125 project_directories=[],
126 project_files=[
127 join('tree', 'project', 'project_members.ndjson'),
128 ],
129 )
131 # Entity: Issues
132 ISSUES = Entity(
133 name='Issues',
134 group_globs=[],
135 project_directories=[],
136 project_files=[
137 join('tree', 'project', 'issues.ndjson'),
138 ],
139 )
141 # Entity: Issue boards
142 BOARDS = Entity(
143 name='Issue boards',
144 group_globs=[],
145 project_directories=[],
146 project_files=[
147 join('tree', 'project', 'boards.ndjson'),
148 ],
149 )
151 # Entity: Milestones
152 MILESTONES = Entity(
153 name='Milestones',
154 group_globs=[],
155 project_directories=[],
156 project_files=[
157 join('tree', 'project', 'milestones.ndjson'),
158 ],
159 )
161 # Entity: Labels
162 LABELS = Entity(
163 name='Labels',
164 group_globs=[],
165 project_directories=[],
166 project_files=[
167 join('tree', 'project', 'labels.ndjson'),
168 ],
169 )
171 # Entity: Repository / Merge_requests
172 MERGE_REQUESTS = Entity(
173 name='Merge requests',
174 group_globs=[],
175 project_directories=[],
176 project_files=[
177 join('tree', 'project', 'merge_requests.ndjson'),
178 ],
179 )
181 # Entity: Repository / LFS objects
182 LFS_OBJECTS = Entity(
183 name='LFS objects',
184 group_globs=[],
185 project_directories=[
186 join('lfs-objects'),
187 ],
188 project_files=[
189 join('lfs-objects.json'),
190 ],
191 )
193 # Entity: Repository / CI/CD Pipelines
194 PIPELINES = Entity(
195 name='Pipelines',
196 group_globs=[],
197 project_directories=[],
198 project_files=[
199 join('tree', 'project', 'ci_pipelines.ndjson'),
200 join('tree', 'project', 'pipeline_schedules.ndjson'),
201 ],
202 )
204 # Entity: Wiki
205 WIKI = Entity(
206 name='Wiki',
207 group_globs=[],
208 project_directories=[],
209 project_files=[
210 join('project.wiki.bundle'),
211 ],
212 )
214 # Entity: Snippets
215 SNIPPETS = Entity(
216 name='Snippets',
217 group_globs=[],
218 project_directories=[
219 join('snippets'),
220 ],
221 project_files=[
222 join('tree', 'project', 'snippets.ndjson'),
223 ],
224 )
226 # Entity: Releases
227 RELEASES = Entity(
228 name='Releases',
229 group_globs=[],
230 project_directories=[],
231 project_files=[
232 join('tree', 'project', 'releases.ndjson'),
233 ],
234 )
236 # Entity: Badges
237 BADGES = Entity(
238 name='Badges',
239 group_globs=[],
240 project_directories=[],
241 project_files=[
242 join('tree', 'project', 'project_badges.ndjson'),
243 ],
244 )
246 # Entity: Uploads (wiki / issues)
247 UPLOADS = Entity(
248 name='Uploads',
249 group_globs=[],
250 project_directories=[
251 join('uploads'),
252 ],
253 project_files=[],
254 )
256 # Remover: Issues
257 REMOVER_ISSUES = Remover(
258 name='Remove/Issues',
259 group_globs=[
260 *MEMBERS.group_globs,
261 *ISSUES.group_globs,
262 *BOARDS.group_globs,
263 *MILESTONES.group_globs,
264 *LABELS.group_globs,
265 *UPLOADS.group_globs,
266 ],
267 project_directories=[
268 *MEMBERS.project_directories,
269 *ISSUES.project_directories,
270 *BOARDS.project_directories,
271 *MILESTONES.project_directories,
272 *LABELS.project_directories,
273 *UPLOADS.project_directories,
274 ],
275 project_files=[
276 *MEMBERS.project_files,
277 *ISSUES.project_files,
278 *BOARDS.project_files,
279 *MILESTONES.project_files,
280 *LABELS.project_files,
281 *UPLOADS.project_files,
282 ],
283 )
285 # Remover: Repository
286 REMOVER_REPOSITORY = Remover(
287 name='Remove/Repository',
288 group_globs=[
289 *MEMBERS.group_globs,
290 *MERGE_REQUESTS.group_globs,
291 *LFS_OBJECTS.group_globs,
292 *PIPELINES.group_globs,
293 *RELEASES.group_globs,
294 ],
295 project_directories=[
296 *MEMBERS.project_directories,
297 *MERGE_REQUESTS.project_directories,
298 *LFS_OBJECTS.project_directories,
299 *PIPELINES.project_directories,
300 *RELEASES.project_directories,
301 ],
302 project_files=[
303 *MEMBERS.project_files,
304 *MERGE_REQUESTS.project_files,
305 *LFS_OBJECTS.project_files,
306 *PIPELINES.project_files,
307 *RELEASES.project_files,
308 join('project.bundle'),
309 join('tree', 'project', 'protected_branches.ndjson'),
310 join('tree', 'project', 'protected_tags.ndjson'),
311 ],
312 )
314 # Remover: Wiki
315 REMOVER_WIKI = Remover(
316 name='Remove/Wiki',
317 group_globs=[
318 *MEMBERS.group_globs,
319 *WIKI.group_globs,
320 ],
321 project_directories=[
322 *MEMBERS.project_directories,
323 *WIKI.project_directories,
324 ],
325 project_files=[
326 *MEMBERS.project_files,
327 *WIKI.project_files,
328 ],
329 )
331 # Template: Issues
332 TEMPLATE_ISSUES = Template(
333 name='Template/Issues',
334 group_globs=[
335 *MEMBERS.group_globs,
336 *ISSUES.group_globs,
337 *MILESTONES.group_globs,
338 *UPLOADS.group_globs,
339 ],
340 project_directories=[
341 *MEMBERS.project_directories,
342 *ISSUES.project_directories,
343 *MILESTONES.project_directories,
344 *UPLOADS.project_directories,
345 ],
346 project_files=[
347 *MEMBERS.project_files,
348 *ISSUES.project_files,
349 *MILESTONES.project_files,
350 *UPLOADS.project_files,
351 ],
352 )
354 # Template: Repository
355 TEMPLATE_REPOSITORY = Template(
356 name='Template/Repository',
357 group_globs=[
358 *MEMBERS.group_globs,
359 *MERGE_REQUESTS.group_globs,
360 *PIPELINES.group_globs,
361 *RELEASES.group_globs,
362 ],
363 project_directories=[
364 *MEMBERS.project_directories,
365 *MERGE_REQUESTS.project_directories,
366 *PIPELINES.project_directories,
367 *RELEASES.project_directories,
368 ],
369 project_files=[
370 *MEMBERS.project_files,
371 *MERGE_REQUESTS.project_files,
372 *PIPELINES.project_files,
373 *RELEASES.project_files,
374 join('tree', 'project', 'protected_tags.ndjson'),
375 ],
376 )
378# RunnerHelpers class, pylint: disable=too-few-public-methods
379class RunnerHelpers:
381 # Active
382 @staticmethod
383 def active(runner: GroupRunner | ProjectRunner) -> bool:
385 # Detect inactive runner
386 if not runner.active:
387 return False
389 # Detect paused runner
390 if (hasattr(runner, 'paused') and runner.paused) or runner.status == 'paused':
391 return False
393 # Result
394 return True