Coverage for pyVersioning/CIService.py: 85%

47 statements  

« prev     ^ index     » next       coverage.py v7.8.2, created at 2025-05-30 22:21 +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, GitShowCommand, BaseService, Platform 

41 

42 

43@export 

44class ServiceException(VersioningException): 

45 """ 

46 .. todo:: 

47 ServiceException needs documentation 

48 

49 """ 

50 

51 

52@export 

53class CIService(BaseService, GitHelperMixin): 

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

55 

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

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

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

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

60 

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

62 """ 

63 .. todo:: 

64 getEnvironment needs documentation 

65 

66 """ 

67 

68 filteredEnv = {key: value for (key, value) in environ.items() if key.startswith(self.ENV_INCLUDE_FILTER) and not key.endswith(self.ENV_EXCLUDE_FILTER)} 

69 

70 # manually add some variables 

71 for key in self.ENV_INCLUDES: 

72 try: 

73 filteredEnv[key] = environ[key] 

74 except KeyError: 

75 pass 

76 

77 # manually delete some variables 

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

79 try: 

80 del filteredEnv[key] 

81 except KeyError: 

82 pass 

83 

84 def func(s): 

85 for e in filteredEnv.keys(): 

86 yield e, s.__getattribute__(e) 

87 

88 Environment = make_dataclass( 

89 "Environment", 

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

91 bases=(SelfDescriptive,), 

92 namespace={ 

93 'as_dict': lambda self: filteredEnv, 

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

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

96 }, 

97 repr=True 

98 ) 

99 

100 return Environment(**filteredEnv) 

101 

102 @abstractmethod 

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

104 """ 

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

106 

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

108 """ 

109 

110 # @abstractmethod 

111 def GetCommitDate(self) -> datetime: 

112 """ 

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

114 

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

116 """ 

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

118 return datetime.fromtimestamp(int(datetimeString)) 

119 

120 @abstractmethod 

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

122 """ 

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

124 

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

126 """ 

127 

128 @abstractmethod 

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

130 """ 

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

132 

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

134 """ 

135 

136 @abstractmethod 

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

138 """ 

139 Returns the Git repository URL. 

140 

141 :return: Git repository URL. 

142 """ 

143 

144 

145@export 

146class WorkStation(BaseService): 

147 def GetPlatform(self) -> Platform: 

148 return Platform("NO-CI")