Coverage for src/P4OO/Label.py: 83%

48 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-09-07 17:17 +0000

1###################################################################### 

2# Copyright (c)2011-2012,2015,2024 David L. Armstrong. 

3# Copyright (c)2012, Cisco Systems, Inc. 

4# 

5# P4OO.Label.py 

6# 

7###################################################################### 

8 

9from dataclasses import dataclass, field 

10 

11from P4OO.Exceptions import P4Warning 

12from P4OO.Change import P4OOChangeSet 

13from P4OO._SpecObj import _P4OOSpecObj 

14from P4OO._Set import _P4OOSet 

15 

16@dataclass(unsafe_hash=True) 

17class P4OOLabel(_P4OOSpecObj): 

18 """ 

19 Perforce Label Spec Object 

20 

21 id Required: Yes 

22 

23 Forcible: Yes 

24 

25 Attributes: 

26 label (str): Name of the label 

27 owner (P4OOUser): User that owns the label spec 

28 description (str): Description field 

29 options (str): [`locked`|`unlocked`|`autoreload`|`noautoreload`] 

30 revision (str): optional revision specification for automatic label 

31 view (str): View spec mappings 

32 update (datetime): Time of last update to the spec 

33 access (datetime): Time of last access of the spec 

34 

35 See Also: 

36 Perforce Helix Core Command Reference: 

37 https://www.perforce.com/manuals/cmdref/Content/CmdRef/p4_label.htm 

38 """ 

39 

40 # Subclasses must define SPECOBJ_TYPE 

41 _SPECOBJ_TYPE = 'label' 

42 

43 def getRevision(self): 

44 """ Return the revision spec attribute of the label """ 

45 

46 return self._getSpecAttr('Revision') 

47 

48 def tagFiles(self, *fileSpec, **kwargs): 

49 """ Tag the specified files against label (self) """ 

50 

51 p4Output = None 

52 p4Output = self._runCommand('tag', label=self, files=fileSpec, 

53 **kwargs) 

54 

55# TODO error checking 

56# try: 

57# p4Output = self._runCommand('add', p4client=self, files=fileSpec, 

58# **kwargs) 

59# except P4Warning as e: 

60# if re.search(r"\nWARNING: File\(s\) up-to-date\.$", str(e)): 

61# pass 

62# else: 

63# raise(e) 

64 

65 return p4Output 

66 

67 def getLastChange(self): 

68 """ Return the latest change incorporated into the label 

69 

70 Return None if the label sees no changes (empty depot). 

71 """ 

72 

73 changeFileRevRange = "@" + self._getSpecID() 

74 

75 changeSet = P4OOChangeSet(_p4Conn=self._getP4Connection()) 

76 p4Changes = changeSet.query(files=changeFileRevRange, maxresults=1) 

77 

78 if len(p4Changes) == 0: 

79 return None 

80 

81 # We only expect one result, we only return one result. 

82 return p4Changes[0] 

83 

84 def getChangesFromLabels(self, otherLabel, client): 

85 """ Fetch the list of changes from this label to another one. 

86 

87 Assumptions: 

88 - self represents the lower of the two labels. If the other 

89 direction is desired, then make the call against the other 

90 label instead. 

91 """ 

92 

93 if not isinstance(otherLabel, P4OOLabel): 

94 raise TypeError(otherLabel) 

95 

96 firstChange = self.getLastChange() 

97 lastChange = otherLabel.getLastChange() 

98 

99 return firstChange.getChangesFromChangeNums(lastChange, client) 

100 

101 def getDiffsFromLabels(self, otherLabel, client, **diffOpts): 

102 """ Fetch the list of diffs from this label to another one """ 

103 

104 if not isinstance(otherLabel, P4OOLabel): 

105 raise TypeError(otherLabel) 

106 

107 firstLabelName = self._getSpecID() 

108 otherLabelName = otherLabel._getSpecID() 

109 

110 diffText = [] 

111 view = client._getSpecAttr('View') 

112 for viewLine in view: 

113 viewSpec = viewLine.split(" ", 2) 

114 

115 firstLabelPath = '%s@%s' % (viewSpec[0], firstLabelName) 

116 otherLabelPath = '%s@%s' % (viewSpec[0], otherLabelName) 

117 

118 try: 

119 # ask for rawOutput so we get the actual diff content, 

120 # not just the diff tags. 

121 viewDiffs = self._runCommand('diff2', 

122 rawOutput=True, 

123 files=[firstLabelPath, 

124 otherLabelPath], 

125 **diffOpts) 

126 diffText.extend(viewDiffs) 

127 

128 except P4Warning: 

129 # This gets thrown if no files exist in view path 

130 pass 

131 

132 return diffText 

133 

134 

135@dataclass 

136class P4OOLabelSet(_P4OOSet): 

137 """ `P4OOSet` of `P4OOLabel` objects """ 

138 

139 def query(self, user: str=None, maxresults: int=None, 

140 namefilter: str=None, files: str=None, **kwargs): 

141 """ 

142 Executes `p4 labels` query 

143 

144 Args: 

145 user (P4OOUser | str, optional): The user that owns the label 

146 maxresults (int, optional): Return only the first [max] results 

147 namefilter (str, optional): Case-sensitive filter on label name 

148 files (P4OOFileSet | P4OOFile | str, optional): The set of file 

149 revisions to query 

150 

151 Returns: 

152 (P4OOLabelSet): `P4OOSet` of `P4OOLabel` objects matching query 

153 parameters 

154 

155 See Also: 

156 Perforce Helix Core Command Reference: 

157 https://www.perforce.com/manuals/cmdref/Content/CmdRef/p4_labels.html 

158 """ 

159 

160 return self._query(setObjType='labels', user=user, 

161 maxresults=maxresults, namefilter=namefilter, 

162 files=files, **kwargs)