Coverage for pyVersioning/CIService.py: 85%

48 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-17 22:22 +0000

1# ==================================================================================================================== # 

2# __ __ _ _ # 

3# _ __ _ \ \ / /__ _ __ ___(_) ___ _ __ (_)_ __ __ _ # 

4# | '_ \| | | \ \ / / _ \ '__/ __| |/ _ \| '_ \| | '_ \ / _` | # 

5# | |_) | |_| |\ V / __/ | \__ \ | (_) | | | | | | | | (_| | # 

6# | .__/ \__, | \_/ \___|_| |___/_|\___/|_| |_|_|_| |_|\__, | # 

7# |_| |___/ |___/ # 

8# ==================================================================================================================== # 

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

13# ==================================================================================================================== # 

14# Copyright 2020-2025 Patrick Lehmann - Bötzingen, Germany # 

15# # 

16# Licensed under the Apache License, Version 2.0 (the "License"); # 

17# you may not use this file except in compliance with the License. # 

18# You may obtain a copy of the License at # 

19# # 

20# http://www.apache.org/licenses/LICENSE-2.0 # 

21# # 

22# Unless required by applicable law or agreed to in writing, software # 

23# distributed under the License is distributed on an "AS IS" BASIS, # 

24# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

25# See the License for the specific language governing permissions and # 

26# limitations under the License. # 

27# # 

28# SPDX-License-Identifier: Apache-2.0 # 

29# ==================================================================================================================== # 

30# 

31"""Module for CI service base classes.""" 

32from dataclasses import make_dataclass 

33from datetime import datetime 

34from os import environ 

35from typing import Dict, Optional as Nullable, Tuple 

36 

37from pyTooling.Decorators import export 

38from pyTooling.MetaClasses import abstractmethod 

39 

40from pyVersioning import VersioningException, GitHelperMixin, SelfDescriptive 

41from pyVersioning import GitShowCommand, BaseService, Platform 

42 

43 

44@export 

45class ServiceException(VersioningException): 

46 """ 

47 .. todo:: 

48 ServiceException needs documentation 

49 

50 """ 

51 

52 

53@export 

54class CIService(BaseService, GitHelperMixin): 

55 """Base-class to collect Git and other platform and environment information from CI service environment variables.""" 

56 

57 ENV_INCLUDE_FILTER: Tuple[str, ...] = () 

58 ENV_EXCLUDE_FILTER: Tuple[str, ...] = () 

59 ENV_INCLUDES: Tuple[str, ...] = () 

60 ENV_EXCLUDES: Tuple[str, ...] = () 

61 

62 def GetEnvironment(self) -> Dict[str, str]: 

63 """ 

64 .. todo:: 

65 getEnvironment needs documentation 

66 

67 """ 

68 

69 filteredEnv = {key: value for (key, value) in environ.items() if key.startswith(self.ENV_INCLUDE_FILTER) and not key.endswith(self.ENV_EXCLUDE_FILTER)} # pylint: disable=line-too-long 

70 

71 # manually add some variables 

72 for key in self.ENV_INCLUDES: 

73 try: 

74 filteredEnv[key] = environ[key] 

75 except KeyError: 

76 pass 

77 

78 # manually delete some variables 

79 for key in self.ENV_EXCLUDES: 79 ↛ 80line 79 didn't jump to line 80 because the loop on line 79 never started

80 try: 

81 del filteredEnv[key] 

82 except KeyError: 

83 pass 

84 

85 def func(s): 

86 for e in filteredEnv.keys(): 

87 yield e, s.__getattribute__(e) 

88 

89 Environment = make_dataclass( 

90 "Environment", 

91 [(name, str) for name in filteredEnv.keys()], 

92 bases=(SelfDescriptive,), 

93 namespace={ 

94 'as_dict': lambda self: filteredEnv, 

95 'Keys': lambda self: filteredEnv.keys(), 

96 'KeyValuePairs': lambda self: func(self) 

97 }, 

98 repr=True 

99 ) 

100 

101 return Environment(**filteredEnv) 

102 

103 @abstractmethod 

104 def GetGitHash(self) -> str: # type: ignore[empty-body] 

105 """ 

106 Returns the Git hash (SHA1 - 160-bit) as a string. 

107 

108 :return: Git hash as a hex formated string (40 characters). 

109 """ 

110 

111 # @abstractmethod 

112 def GetCommitDate(self) -> datetime: 

113 """ 

114 Returns the commit date as a :class:`~datetime.datetime`. 

115 

116 :return: Git commit date as :class:`~datetime.datetime`. 

117 """ 

118 datetimeString = self.ExecuteGitShow(GitShowCommand.CommitDateTime, self.GetGitHash()) 

119 return datetime.fromtimestamp(int(datetimeString)) 

120 

121 @abstractmethod 

122 def GetGitBranch(self) -> Nullable[str]: # type: ignore[empty-body] 

123 """ 

124 Returns Git branch name or ``None`` is not checked out on a branch. 

125 

126 :return: Git branch name or ``None``. 

127 """ 

128 

129 @abstractmethod 

130 def GetGitTag(self) -> Nullable[str]: # type: ignore[empty-body] 

131 """ 

132 Returns Git tag name or ``None`` is not checked out on a branch. 

133 

134 :return: Git tag name or ``None``. 

135 """ 

136 

137 @abstractmethod 

138 def GetGitRepository(self) -> str: # type: ignore[empty-body] 

139 """ 

140 Returns the Git repository URL. 

141 

142 :return: Git repository URL. 

143 """ 

144 

145 

146@export 

147class WorkStation(BaseService): 

148 def GetPlatform(self) -> Platform: 

149 return Platform("NO-CI")