15 |
15 |
16 |
16 |
17 class HgDiffGenerator(QObject): |
17 class HgDiffGenerator(QObject): |
18 """ |
18 """ |
19 Class implementing the generation of output of the hg diff command. |
19 Class implementing the generation of output of the hg diff command. |
20 |
20 |
21 @signal finished() emitted when all processes have finished |
21 @signal finished() emitted when all processes have finished |
22 """ |
22 """ |
|
23 |
23 finished = pyqtSignal() |
24 finished = pyqtSignal() |
24 |
25 |
25 def __init__(self, vcs, parent=None): |
26 def __init__(self, vcs, parent=None): |
26 """ |
27 """ |
27 Constructor |
28 Constructor |
28 |
29 |
29 @param vcs reference to the vcs object |
30 @param vcs reference to the vcs object |
30 @param parent parent widget (QWidget) |
31 @param parent parent widget (QWidget) |
31 """ |
32 """ |
32 super().__init__(parent) |
33 super().__init__(parent) |
33 |
34 |
34 self.vcs = vcs |
35 self.vcs = vcs |
35 |
36 |
36 self.__hgClient = self.vcs.getClient() |
37 self.__hgClient = self.vcs.getClient() |
37 |
38 |
38 def stopProcess(self): |
39 def stopProcess(self): |
39 """ |
40 """ |
40 Public slot to stop the diff process. |
41 Public slot to stop the diff process. |
41 """ |
42 """ |
42 if self.__hgClient.isExecuting(): |
43 if self.__hgClient.isExecuting(): |
43 self.__hgClient.cancel() |
44 self.__hgClient.cancel() |
44 |
45 |
45 def __getVersionArg(self, version): |
46 def __getVersionArg(self, version): |
46 """ |
47 """ |
47 Private method to get a hg revision argument for the given revision. |
48 Private method to get a hg revision argument for the given revision. |
48 |
49 |
49 @param version revision (integer or string) |
50 @param version revision (integer or string) |
50 @return version argument (string) |
51 @return version argument (string) |
51 """ |
52 """ |
52 if version == "WORKING": |
53 if version == "WORKING": |
53 return None |
54 return None |
54 else: |
55 else: |
55 return str(version).strip() |
56 return str(version).strip() |
56 |
57 |
57 def start(self, fn, versions=None, bundle=None, qdiff=False): |
58 def start(self, fn, versions=None, bundle=None, qdiff=False): |
58 """ |
59 """ |
59 Public slot to start the hg diff command. |
60 Public slot to start the hg diff command. |
60 |
61 |
61 @param fn filename to be diffed (string) |
62 @param fn filename to be diffed (string) |
62 @param versions list of versions to be diffed (list of up to |
63 @param versions list of versions to be diffed (list of up to |
63 2 strings or None) |
64 2 strings or None) |
64 @param bundle name of a bundle file (string) |
65 @param bundle name of a bundle file (string) |
65 @param qdiff flag indicating qdiff command shall be used (boolean) |
66 @param qdiff flag indicating qdiff command shall be used (boolean) |
68 """ |
69 """ |
69 if qdiff: |
70 if qdiff: |
70 args = self.vcs.initCommand("qdiff") |
71 args = self.vcs.initCommand("qdiff") |
71 else: |
72 else: |
72 args = self.vcs.initCommand("diff") |
73 args = self.vcs.initCommand("diff") |
73 |
74 |
74 if self.vcs.hasSubrepositories(): |
75 if self.vcs.hasSubrepositories(): |
75 args.append("--subrepos") |
76 args.append("--subrepos") |
76 |
77 |
77 if bundle: |
78 if bundle: |
78 args.append('--repository') |
79 args.append("--repository") |
79 args.append(bundle) |
80 args.append(bundle) |
80 elif ( |
81 elif self.vcs.bundleFile and os.path.exists(self.vcs.bundleFile): |
81 self.vcs.bundleFile and |
82 args.append("--repository") |
82 os.path.exists(self.vcs.bundleFile) |
|
83 ): |
|
84 args.append('--repository') |
|
85 args.append(self.vcs.bundleFile) |
83 args.append(self.vcs.bundleFile) |
86 |
84 |
87 if versions is not None: |
85 if versions is not None: |
88 rev1 = self.__getVersionArg(versions[0]) |
86 rev1 = self.__getVersionArg(versions[0]) |
89 rev2 = None |
87 rev2 = None |
90 if len(versions) == 2: |
88 if len(versions) == 2: |
91 rev2 = self.__getVersionArg(versions[1]) |
89 rev2 = self.__getVersionArg(versions[1]) |
92 |
90 |
93 if rev1 is not None or rev2 is not None: |
91 if rev1 is not None or rev2 is not None: |
94 if self.vcs.version >= (5, 7, 0): |
92 if self.vcs.version >= (5, 7, 0): |
95 if rev1 is not None: |
93 if rev1 is not None: |
96 args += ["--from", rev1] |
94 args += ["--from", rev1] |
97 if rev2 is not None: |
95 if rev2 is not None: |
98 args += ["--to", rev2] |
96 args += ["--to", rev2] |
99 else: |
97 else: |
100 args.append('-r') |
98 args.append("-r") |
101 if rev1 is not None and rev2 is not None: |
99 if rev1 is not None and rev2 is not None: |
102 args.append('{0}:{1}'.format(rev1, rev2)) |
100 args.append("{0}:{1}".format(rev1, rev2)) |
103 elif rev2 is None: |
101 elif rev2 is None: |
104 args.append(rev1) |
102 args.append(rev1) |
105 elif rev1 is None: |
103 elif rev1 is None: |
106 args.append(':{0}'.format(rev2)) |
104 args.append(":{0}".format(rev2)) |
107 |
105 |
108 if fn: |
106 if fn: |
109 if isinstance(fn, list): |
107 if isinstance(fn, list): |
110 self.vcs.addArguments(args, fn) |
108 self.vcs.addArguments(args, fn) |
111 else: |
109 else: |
112 args.append(fn) |
110 args.append(fn) |
113 |
111 |
114 self.__oldFile = "" |
112 self.__oldFile = "" |
115 self.__oldFileLine = -1 |
113 self.__oldFileLine = -1 |
116 self.__fileSeparators = [] |
114 self.__fileSeparators = [] |
117 self.__output = [] |
115 self.__output = [] |
118 self.__errors = [] |
116 self.__errors = [] |
119 |
117 |
120 with EricOverrideCursor(): |
118 with EricOverrideCursor(): |
121 out, err = self.__hgClient.runcommand(args) |
119 out, err = self.__hgClient.runcommand(args) |
122 |
120 |
123 if err: |
121 if err: |
124 self.__errors = err.splitlines(True) |
122 self.__errors = err.splitlines(True) |
125 |
123 |
126 if out: |
124 if out: |
127 self.__output = out.splitlines(True) |
125 self.__output = out.splitlines(True) |
128 for lineno, line in enumerate(self.__output): |
126 for lineno, line in enumerate(self.__output): |
129 if line.startswith(("--- ", "+++ ")): |
127 if line.startswith(("--- ", "+++ ")): |
130 self.__processFileLine(lineno, line) |
128 self.__processFileLine(lineno, line) |
131 if self.__hgClient.wasCanceled(): |
129 if self.__hgClient.wasCanceled(): |
132 break |
130 break |
133 |
131 |
134 self.__finish() |
132 self.__finish() |
135 |
133 |
136 return True |
134 return True |
137 |
135 |
138 def __finish(self): |
136 def __finish(self): |
139 """ |
137 """ |
140 Private slot called when the process finished or the user pressed |
138 Private slot called when the process finished or the user pressed |
141 the button. |
139 the button. |
142 """ |
140 """ |
143 self.finished.emit() |
141 self.finished.emit() |
144 |
142 |
145 def getResult(self): |
143 def getResult(self): |
146 """ |
144 """ |
147 Public method to return the result data. |
145 Public method to return the result data. |
148 |
146 |
149 @return tuple of lists of string containing lines of the diff, the |
147 @return tuple of lists of string containing lines of the diff, the |
150 list of errors and a list of tuples of filenames and the line |
148 list of errors and a list of tuples of filenames and the line |
151 into the diff output. |
149 into the diff output. |
152 """ |
150 """ |
153 return (self.__output, self.__errors, self.__fileSeparators) |
151 return (self.__output, self.__errors, self.__fileSeparators) |
154 |
152 |
155 def __extractFileName(self, line): |
153 def __extractFileName(self, line): |
156 """ |
154 """ |
157 Private method to extract the file name out of a file separator line. |
155 Private method to extract the file name out of a file separator line. |
158 |
156 |
159 @param line line to be processed (string) |
157 @param line line to be processed (string) |
160 @return extracted file name (string) |
158 @return extracted file name (string) |
161 """ |
159 """ |
162 f = line.split(None, 1)[1] |
160 f = line.split(None, 1)[1] |
163 f = f.rsplit(None, 6)[0] |
161 f = f.rsplit(None, 6)[0] |
164 f = "__NULL__" if f == "/dev/null" else f.split("/", 1)[1] |
162 f = "__NULL__" if f == "/dev/null" else f.split("/", 1)[1] |
165 return f |
163 return f |
166 |
164 |
167 def __processFileLine(self, lineno, line): |
165 def __processFileLine(self, lineno, line): |
168 """ |
166 """ |
169 Private slot to process a line giving the old/new file. |
167 Private slot to process a line giving the old/new file. |
170 |
168 |
171 @param lineno line number of line to be processed |
169 @param lineno line number of line to be processed |
172 @type int |
170 @type int |
173 @param line line to be processed |
171 @param line line to be processed |
174 @type str |
172 @type str |
175 """ |
173 """ |
176 if line.startswith('---'): |
174 if line.startswith("---"): |
177 self.__oldFileLine = lineno |
175 self.__oldFileLine = lineno |
178 self.__oldFile = self.__extractFileName(line) |
176 self.__oldFile = self.__extractFileName(line) |
179 else: |
177 else: |
180 newFile = self.__extractFileName(line) |
178 newFile = self.__extractFileName(line) |
181 if self.__oldFile == "__NULL__": |
179 if self.__oldFile == "__NULL__": |
182 self.__fileSeparators.append( |
180 self.__fileSeparators.append((newFile, newFile, self.__oldFileLine)) |
183 (newFile, newFile, self.__oldFileLine)) |
|
184 else: |
181 else: |
185 self.__fileSeparators.append( |
182 self.__fileSeparators.append( |
186 (self.__oldFile, newFile, self.__oldFileLine)) |
183 (self.__oldFile, newFile, self.__oldFileLine) |
|
184 ) |