aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/clearcase/clearcasesync.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/clearcase/clearcasesync.cpp')
-rw-r--r--src/plugins/clearcase/clearcasesync.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/plugins/clearcase/clearcasesync.cpp b/src/plugins/clearcase/clearcasesync.cpp
new file mode 100644
index 00000000000..3877e62596f
--- /dev/null
+++ b/src/plugins/clearcase/clearcasesync.cpp
@@ -0,0 +1,125 @@
+#include "clearcasesync.h"
+
+#include <QDir>
+#include <QFutureInterface>
+#include <QProcess>
+#include <QStringList>
+
+namespace ClearCase {
+namespace Internal {
+
+ClearCaseSync::ClearCaseSync(ClearCasePlugin *plugin, QSharedPointer<StatusMap> statusMap) :
+ m_plugin(plugin),
+ m_statusMap(statusMap)
+{
+}
+
+void ClearCaseSync::run(QFutureInterface<void> &future, const QString &topLevel, QStringList &files)
+{
+ ClearCaseSettings settings = m_plugin->settings();
+ QString program = settings.ccBinaryPath;
+ if (program.isEmpty())
+ return;
+ int total = files.size();
+ bool hot = (total < 10);
+ int processed = 0;
+ QString view = m_plugin->currentView();
+ if (view.isEmpty())
+ emit updateStreamAndView();
+ if (!hot)
+ total = settings.totalFiles.value(view, total);
+
+ // refresh activities list
+ m_plugin->refreshActivities();
+
+ if (settings.disableIndexer)
+ return;
+ QStringList vobs;
+ if (!settings.indexOnlyVOBs.isEmpty())
+ vobs = settings.indexOnlyVOBs.split(QLatin1Char(','));
+ else
+ vobs = m_plugin->ccGetActiveVobs();
+ QDir topLevelDir(topLevel);
+ QStringList args(QLatin1String("ls"));
+ if (hot) {
+ // find all files whose permissions changed OR hijacked files
+ // (might have become checked out)
+ foreach (const QString &file, m_statusMap->keys()) {
+ bool permChanged =
+ m_statusMap->value(file).permissions != QFileInfo(topLevel, file).permissions();
+ if (permChanged || m_statusMap->value(file).status == FileStatus::Hijacked) {
+ files.append(file);
+ (*m_statusMap)[file].status = FileStatus::Unknown;
+ ++total;
+ }
+ }
+ args << files;
+ } else {
+ foreach (const QString &file, files)
+ emit setStatus(topLevelDir.relativeFilePath(file), FileStatus::Unknown, false);
+ args << QLatin1String("-recurse");
+ args << vobs;
+ }
+
+ // adding 1 for initial sync in which total is not accurate, to prevent finishing
+ // (we don't want it to become green)
+ future.setProgressRange(0, total + 1);
+ QProcess process;
+ process.setWorkingDirectory(topLevel);
+ process.start(program, args);
+ if (!process.waitForStarted())
+ return;
+ QString buffer;
+ while (process.waitForReadyRead() && !future.isCanceled()) {
+ while (process.state() == QProcess::Running &&
+ process.bytesAvailable() && !future.isCanceled())
+ {
+ QString line = QString::fromLocal8Bit(process.readLine().constData());
+ buffer += line;
+ if (buffer.endsWith(QLatin1Char('\n')) || process.atEnd()) {
+ int atatpos = buffer.indexOf(QLatin1String("@@"));
+ if (atatpos != -1) { // probably managed file
+ // find first whitespace. anything before that is not interesting
+ int wspos = buffer.indexOf(QRegExp(QLatin1String("\\s")));
+ const QString file = QDir::fromNativeSeparators(buffer.left(atatpos));
+ QString ccState;
+ QRegExp reState(QLatin1String("^\\s*\\[[^\\]]*\\]")); // [hijacked]; [loaded but missing]
+ if (reState.indexIn(buffer, wspos + 1, QRegExp::CaretAtOffset) != -1) {
+ ccState = reState.cap();
+ if (ccState.indexOf(QLatin1String("hijacked")) != -1)
+ emit setStatus(file, FileStatus::Hijacked, true);
+ else if (ccState.indexOf(QLatin1String("loaded but missing")) != -1)
+ emit setStatus(file, FileStatus::Missing, false);
+ }
+ else if (buffer.lastIndexOf(QLatin1String("CHECKEDOUT"), wspos) != -1)
+ emit setStatus(file, FileStatus::CheckedOut, true);
+ // don't care about checked-in files not listed in project
+ else if (m_statusMap->contains(file))
+ emit setStatus(file, FileStatus::CheckedIn, true);
+ }
+ buffer.clear();
+ future.setProgressValue(qMin(total, ++processed));
+ }
+ }
+ }
+
+ if (!future.isCanceled()) {
+ foreach (const QString &file, files) {
+ QString relFile = topLevelDir.relativeFilePath(file);
+ if (m_statusMap->value(relFile).status == FileStatus::Unknown)
+ emit setStatus(relFile, FileStatus::NotManaged, false);
+ }
+ future.setProgressValue(total + 1);
+ if (!hot) {
+ settings = m_plugin->settings(); // Might have changed while task was running
+ settings.totalFiles[view] = processed;
+ m_plugin->setSettings(settings);
+ }
+ }
+ if (process.state() == QProcess::Running)
+ process.kill();
+ process.waitForFinished();
+}
+
+} // namespace Internal
+} // namespace ClearCase