Coverage for src/gitlabracadabra/mixins/labels.py: 70%

47 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-10 17:02 +0100

1# Copyright (C) 2019-2025 Mathieu Parent <math.parent@gmail.com> 

2# 

3# This program is free software: you can redistribute it and/or modify 

4# it under the terms of the GNU Lesser General Public License as published by 

5# the Free Software Foundation, either version 3 of the License, or 

6# (at your option) any later version. 

7# 

8# This program is distributed in the hope that it will be useful, 

9# but WITHOUT ANY WARRANTY; without even the implied warranty of 

10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

11# GNU Lesser General Public License for more details. 

12# 

13# You should have received a copy of the GNU Lesser General Public License 

14# along with this program. If not, see <http://www.gnu.org/licenses/>. 

15 

16import logging 

17from copy import deepcopy 

18 

19from gitlabracadabra.objects.object import GitLabracadabraObject 

20 

21logger = logging.getLogger(__name__) 

22 

23 

24class LabelsMixin(GitLabracadabraObject): 

25 """Object with labels.""" 

26 

27 """_process_labels() 

28 

29 Process the labels param. 

30 """ 

31 

32 def _process_labels(self, param_name, param_value, *, dry_run=False, skip_save=False): 

33 assert param_name == "labels" # noqa: S101 

34 assert not skip_save # noqa: S101 

35 unknown_labels = self._content.get("unknown_labels", "warn") 

36 try: 

37 current_labels = dict( 

38 [[current_label.name, current_label] for current_label in self._obj.labels.list(all=True)] 

39 ) 

40 except AttributeError: 

41 # https://github.com/python-gitlab/python-gitlab/pull/847 

42 logger.error( 

43 "[%s] Unable to manage labels: %s", self._name, "group labels requires python-gitlab >= 1.11.0" 

44 ) 

45 return 

46 target_labels = dict([[target_label["name"], deepcopy(target_label)] for target_label in param_value]) 

47 # We first check for already existing labels 

48 for current_label_name, current_label in sorted(current_labels.items()): 

49 if current_label_name in target_labels: 

50 for target_label_param_name, target_label_param_value in sorted( 

51 target_labels[current_label_name].items() 

52 ): 

53 try: 

54 current_label_param_value = getattr(current_label, target_label_param_name) 

55 except AttributeError: 

56 logger.info( 

57 "[%s] NOT Changing label %s %s: %s -> %s (current value is not available)", 

58 self._name, 

59 current_label_name, 

60 target_label_param_name, 

61 None, 

62 target_label_param_value, 

63 ) 

64 continue 

65 if target_label_param_name == "description" and current_label_param_value is None: 65 ↛ 66line 65 didn't jump to line 66 because the condition on line 65 was never true

66 current_label_param_value = "" 

67 if current_label_param_value != target_label_param_value: 

68 if dry_run: 68 ↛ 69line 68 didn't jump to line 69 because the condition on line 68 was never true

69 logger.info( 

70 "[%s] NOT Changing label %s %s: %s -> %s (dry-run)", 

71 self._name, 

72 current_label_name, 

73 target_label_param_name, 

74 current_label_param_value, 

75 target_label_param_value, 

76 ) 

77 else: 

78 logger.info( 

79 "[%s] Changing label %s %s: %s -> %s", 

80 self._name, 

81 current_label_name, 

82 target_label_param_name, 

83 current_label_param_value, 

84 target_label_param_value, 

85 ) 

86 setattr(current_label, target_label_param_name, target_label_param_value) 

87 current_label.save() 

88 target_labels.pop(current_label_name) 

89 else: 

90 if self.__class__.__name__ == "GitLabracadabraProject" and not getattr( 90 ↛ 94line 90 didn't jump to line 94 because the condition on line 90 was never true

91 current_label, "is_project_label", False 

92 ): 

93 # Ignore group-level labels on projects 

94 continue 

95 if unknown_labels in ["delete", "remove"]: 95 ↛ 101line 95 didn't jump to line 101 because the condition on line 95 was always true

96 if dry_run: 96 ↛ 97line 96 didn't jump to line 97 because the condition on line 96 was never true

97 logger.info("[%s] NOT Removing label %s (dry-run)", self._name, current_label_name) 

98 else: 

99 logger.info("[%s] Removing label %s", self._name, current_label_name) 

100 current_label.delete() 

101 elif unknown_labels not in ["ignore", "skip"]: 

102 logger.warning("[%s] NOT Removing label: %s", self._name, current_label_name) 

103 # Remaining labels 

104 for target_label_name, target_label in sorted(target_labels.items()): 

105 if dry_run: 105 ↛ 106line 105 didn't jump to line 106 because the condition on line 105 was never true

106 logger.info( 

107 "[%s] NOT Adding label %s: %s -> %s (dry-run)", self._name, target_label_name, None, target_label 

108 ) 

109 else: 

110 logger.info("[%s] Adding label %s: %s -> %s", self._name, target_label_name, None, target_label) 

111 self._obj.labels.create(target_label)