Coverage for pyVersioning / CIService.py: 78%

48 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-13 23:48 +0000

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

2# __ __ _ _ # 

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

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

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

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

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

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

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

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

14# Copyright 2020-2026 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 # slots=True, 

99 repr=True 

100 ) 

101 

102 return Environment(**filteredEnv) 

103 

104 @abstractmethod 

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

106 """ 

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

108 

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

110 """ 

111 

112 # @abstractmethod 

113 def GetCommitDate(self) -> datetime: 

114 """ 

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

116 

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

118 """ 

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

120 return datetime.fromtimestamp(int(datetimeString)) 

121 

122 @abstractmethod 

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

124 """ 

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

126 

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

128 """ 

129 

130 @abstractmethod 

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

132 """ 

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

134 

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

136 """ 

137 

138 @abstractmethod 

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

140 """ 

141 Returns the Git repository URL. 

142 

143 :return: Git repository URL. 

144 """ 

145 

146 

147@export 

148class WorkStation(BaseService): 

149 def GetPlatform(self) -> Platform: 

150 return Platform("NO-CI")