18 |
18 |
19 class SvnStatusMonitorThread(VcsStatusMonitorThread): |
19 class SvnStatusMonitorThread(VcsStatusMonitorThread): |
20 """ |
20 """ |
21 Class implementing the VCS status monitor thread class for Subversion. |
21 Class implementing the VCS status monitor thread class for Subversion. |
22 """ |
22 """ |
|
23 |
23 def __init__(self, interval, project, vcs, parent=None): |
24 def __init__(self, interval, project, vcs, parent=None): |
24 """ |
25 """ |
25 Constructor |
26 Constructor |
26 |
27 |
27 @param interval new interval in seconds (integer) |
28 @param interval new interval in seconds (integer) |
28 @param project reference to the project object (Project) |
29 @param project reference to the project object (Project) |
29 @param vcs reference to the version control object |
30 @param vcs reference to the version control object |
30 @param parent reference to the parent object (QObject) |
31 @param parent reference to the parent object (QObject) |
31 """ |
32 """ |
32 VcsStatusMonitorThread.__init__(self, interval, project, vcs, parent) |
33 VcsStatusMonitorThread.__init__(self, interval, project, vcs, parent) |
33 |
34 |
34 self.__ioEncoding = Preferences.getSystem("IOEncoding") |
35 self.__ioEncoding = Preferences.getSystem("IOEncoding") |
35 |
36 |
36 self.rx_status1 = re.compile('(.{8,9})\\s+([0-9-]+)\\s+(.+)\\s*') |
37 self.rx_status1 = re.compile("(.{8,9})\\s+([0-9-]+)\\s+(.+)\\s*") |
37 self.rx_status2 = re.compile( |
38 self.rx_status2 = re.compile( |
38 '(.{8,9})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)\\s*') |
39 "(.{8,9})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)\\s*" |
39 |
40 ) |
|
41 |
40 def _performMonitor(self): |
42 def _performMonitor(self): |
41 """ |
43 """ |
42 Protected method implementing the monitoring action. |
44 Protected method implementing the monitoring action. |
43 |
45 |
44 This method populates the statusList member variable |
46 This method populates the statusList member variable |
45 with a list of strings giving the status in the first column and the |
47 with a list of strings giving the status in the first column and the |
46 path relative to the project directory starting with the third column. |
48 path relative to the project directory starting with the third column. |
47 The allowed status flags are: |
49 The allowed status flags are: |
48 <ul> |
50 <ul> |
54 <li>"Z" path contains a conflict</li> |
56 <li>"Z" path contains a conflict</li> |
55 <li>"?" path is not tracked</li> |
57 <li>"?" path is not tracked</li> |
56 <li>"!" path is missing</li> |
58 <li>"!" path is missing</li> |
57 <li>" " path is back at normal</li> |
59 <li>" " path is back at normal</li> |
58 </ul> |
60 </ul> |
59 |
61 |
60 @return tuple of flag indicating successful operation (boolean) and |
62 @return tuple of flag indicating successful operation (boolean) and |
61 a status message in case of non successful operation (string) |
63 a status message in case of non successful operation (string) |
62 """ |
64 """ |
63 self.shouldUpdate = False |
65 self.shouldUpdate = False |
64 |
66 |
65 process = QProcess() |
67 process = QProcess() |
66 args = [] |
68 args = [] |
67 args.append('status') |
69 args.append("status") |
68 if not Preferences.getVCS("MonitorLocalStatus"): |
70 if not Preferences.getVCS("MonitorLocalStatus"): |
69 args.append('--show-updates') |
71 args.append("--show-updates") |
70 args.append('--non-interactive') |
72 args.append("--non-interactive") |
71 args.append('.') |
73 args.append(".") |
72 process.setWorkingDirectory(self.projectDir) |
74 process.setWorkingDirectory(self.projectDir) |
73 process.start('svn', args) |
75 process.start("svn", args) |
74 procStarted = process.waitForStarted(5000) |
76 procStarted = process.waitForStarted(5000) |
75 if procStarted: |
77 if procStarted: |
76 finished = process.waitForFinished(300000) |
78 finished = process.waitForFinished(300000) |
77 if finished and process.exitCode() == 0: |
79 if finished and process.exitCode() == 0: |
78 output = str(process.readAllStandardOutput(), |
80 output = str( |
79 self.__ioEncoding, 'replace') |
81 process.readAllStandardOutput(), self.__ioEncoding, "replace" |
|
82 ) |
80 states = {} |
83 states = {} |
81 for line in output.splitlines(): |
84 for line in output.splitlines(): |
82 match = ( |
85 match = self.rx_status1.fullmatch( |
83 self.rx_status1.fullmatch(line) or |
86 line |
84 self.rx_status2.fullmatch(line) |
87 ) or self.rx_status2.fullmatch(line) |
85 ) |
|
86 if match is None: |
88 if match is None: |
87 continue |
89 continue |
88 elif match.re is self.rx_status1: |
90 elif match.re is self.rx_status1: |
89 flags = match.group(1) |
91 flags = match.group(1) |
90 path = match.group(3).strip() |
92 path = match.group(3).strip() |
91 elif match.re is self.rx_status2: |
93 elif match.re is self.rx_status2: |
92 flags = match.group(1) |
94 flags = match.group(1) |
93 path = match.group(5).strip() |
95 path = match.group(5).strip() |
94 if ( |
96 if ( |
95 flags[0] in "ACDMR?!" or |
97 flags[0] in "ACDMR?!" |
96 (flags[0] == " " and flags[-1] == "*") or |
98 or (flags[0] == " " and flags[-1] == "*") |
97 flags[1] in "CM" |
99 or flags[1] in "CM" |
98 ): |
100 ): |
99 if flags[-1] == "*": |
101 if flags[-1] == "*": |
100 status = "U" |
102 status = "U" |
101 else: |
103 else: |
102 status = flags[0] |
104 status = flags[0] |
103 if status == "C" or flags[1] == "C": |
105 if status == "C" or flags[1] == "C": |
104 status = "Z" # give it highest priority |
106 status = "Z" # give it highest priority |
105 elif status == "D": |
107 elif status == "D": |
106 status = "O" |
108 status = "O" |
107 if status == "U": |
109 if status == "U": |
108 self.shouldUpdate = True |
110 self.shouldUpdate = True |
109 if status == " " and flags[1] == "M": |
111 if status == " " and flags[1] == "M": |
110 status = "M" |
112 status = "M" |
111 name = path |
113 name = path |
112 states[name] = status |
114 states[name] = status |
113 try: |
115 try: |
114 if self.reportedStates[name] != status: |
116 if self.reportedStates[name] != status: |
115 self.statusList.append( |
117 self.statusList.append("{0} {1}".format(status, name)) |
116 "{0} {1}".format(status, name)) |
|
117 except KeyError: |
118 except KeyError: |
118 self.statusList.append( |
119 self.statusList.append("{0} {1}".format(status, name)) |
119 "{0} {1}".format(status, name)) |
|
120 for name in list(self.reportedStates.keys()): |
120 for name in list(self.reportedStates.keys()): |
121 if name not in states: |
121 if name not in states: |
122 self.statusList.append(" {0}".format(name)) |
122 self.statusList.append(" {0}".format(name)) |
123 self.reportedStates = states |
123 self.reportedStates = states |
124 return True, self.tr( |
124 return True, self.tr( |
125 "Subversion status checked successfully (using svn)") |
125 "Subversion status checked successfully (using svn)" |
|
126 ) |
126 else: |
127 else: |
127 process.kill() |
128 process.kill() |
128 process.waitForFinished() |
129 process.waitForFinished() |
129 return ( |
130 return ( |
130 False, |
131 False, |
131 str(process.readAllStandardError(), |
132 str( |
|
133 process.readAllStandardError(), |
132 Preferences.getSystem("IOEncoding"), |
134 Preferences.getSystem("IOEncoding"), |
133 'replace') |
135 "replace", |
|
136 ), |
134 ) |
137 ) |
135 else: |
138 else: |
136 process.kill() |
139 process.kill() |
137 process.waitForFinished() |
140 process.waitForFinished() |
138 return False, self.tr( |
141 return False, self.tr("Could not start the Subversion process.") |
139 "Could not start the Subversion process.") |
|