Don't keep compiling/run if something failed.
[kdevelopdvcssupport.git] / plugins / cvs / cvsfileinfoprovider.cpp
blob69eba58cb0656bcdb217a5c3524ce973dccebf9e
1 /***************************************************************************
2 * Copyright 2007 Robert Gruber <rgruber@users.sourceforge.net> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 ***************************************************************************/
11 #include "cvsfileinfoprovider.h"
13 #include <KDebug>
14 #include <QDir>
16 #include "cvsproxy.h"
17 #include "cvsjob.h"
19 CvsFileInfoProvider::CvsFileInfoProvider(CvsProxy * proxy, QObject* parent)
20 : QObject(parent), m_proxy(proxy)
24 CvsFileInfoProvider::~CvsFileInfoProvider()
28 bool CvsFileInfoProvider::requestStatusASync(const KUrl & directory, KDevelop::IVersionControl::WorkingMode mode)
30 bool recursive = (mode == KDevelop::IVersionControl::Recursive)?true:false;
32 CvsJob* job = m_proxy->status( directory.path(), recursive );
33 if (job) {
34 connect(job, SIGNAL( result(KJob*) ),
35 this, SLOT( slotJobFinished(KJob*) ));
37 // Mergind stdout and stderr is needed in this case, as K3Process will not emit the stderr signal
38 // immediately when stderr output is received. As cvs tells directory changes via stderr, we would
39 // be unable to tell which part from the output to stdout belongs to which directory.
40 job->setCommunicationMode( K3Process::Stdout | K3Process::MergedStderr );
41 ICore::self()->runProvider()->registerJob(job);
42 return true;
45 return false;
48 QList< KDevelop::VcsFileInfo > CvsFileInfoProvider::requestStatusSync(const KUrl & directory, KDevelop::IVersionControl::WorkingMode mode)
50 bool recursive = (mode == KDevelop::IVersionControl::Recursive)?true:false;
52 CvsJob* job = m_proxy->status( directory.path(), recursive );
54 //see comment in requestStatusASync() why we do this here
55 job->setCommunicationMode( K3Process::Stdout | K3Process::MergedStderr );
57 if ( job->exec() ) {
58 QList<KDevelop::VcsFileInfo> infos;
59 parseOutput(job->output(), infos);
61 kDebug(9500) << "Fetched status in sync:";
62 foreach (KDevelop::VcsFileInfo info, infos) {
63 kDebug(9500) << info.toString();
66 return infos;
68 return QList<KDevelop::VcsFileInfo>();
71 void CvsFileInfoProvider::slotJobFinished(KJob * job)
73 if ( job->error() )
75 return;
78 CvsJob * cvsjob = dynamic_cast<CvsJob*>(job);
79 if (!cvsjob) {
80 return;
83 QList<KDevelop::VcsFileInfo> infos;
84 parseOutput(cvsjob->output(), infos);
86 foreach (KDevelop::VcsFileInfo info, infos) {
87 kDebug(9500) << info.toString();
90 emit statusReady( infos );
93 void CvsFileInfoProvider::parseOutput(const QString & output, QList<KDevelop::VcsFileInfo>& infos)
95 QString filename;
96 QString status;
97 QString reporev;
98 QString workrev;
100 static QRegExp re_start("^=+$");
101 static QRegExp re_file("File:\\s+(.*)\\s+Status:\\s+(.*)");
102 static QRegExp re_workrev("\\s+Working revision:\\s+([\\d\\.]*).*");
103 static QRegExp re_reporev("\\s+Repository revision:\\s+([\\d\\.]*).*");
104 static QRegExp re_dirchange("cvs status: Examining\\s+(.*)");
106 QString currentDir;
108 QStringList lines = output.split("\n");
109 for (int i=0; i<lines.count(); ++i) {
110 QString s = lines[i];
112 if (s.isEmpty())
113 continue;
115 if ( re_start.exactMatch(s) ) {
116 if ( !filename.isEmpty() ) {
117 // kDebug(9500) << "File:" << filename << "Status:" << status
118 // << "working:" << workrev << "repo:" << reporev << endl;
120 // join the current directory (if any) and the found filename ...
121 QString file = currentDir;
122 if (file.length() > 0)
123 file += QDir::separator();
124 file += filename;
126 // ... and create a VcsFileInfo entry
127 KDevelop::VcsFileInfo info( file, workrev, reporev,
128 String2EnumState( status ) );
129 infos << info;
131 filename.clear();
132 status.clear();
133 reporev.clear();
134 workrev.clear();
135 } else if ( re_file.exactMatch(s) ) {
136 filename = re_file.cap(1).trimmed();
137 status = re_file.cap(2).trimmed();
138 } else if ( re_workrev.exactMatch(s) ) {
139 workrev = re_workrev.cap(1);
140 } else if ( re_reporev.exactMatch(s) ) {
141 reporev = re_reporev.cap(1);
142 } else if ( re_dirchange.exactMatch(s) ) {
143 currentDir = re_dirchange.cap(1);
144 if (currentDir == ".")
145 currentDir.clear();
150 KDevelop::VcsFileInfo::VcsFileState CvsFileInfoProvider::String2EnumState(const QString& stateAsString)
152 if (stateAsString == "Up-to-date")
153 return KDevelop::VcsFileInfo::Uptodate;
154 else if (stateAsString == "Locally Modified")
155 return KDevelop::VcsFileInfo::Modified;
156 else if (stateAsString == "Locally Added")
157 return KDevelop::VcsFileInfo::Added;
158 else if (stateAsString == "Unresolved Conflict")
159 return KDevelop::VcsFileInfo::Conflict;
160 else if (stateAsString == "Needs Patch")
161 return KDevelop::VcsFileInfo::NeedsPatch;
162 else if (stateAsString == "Needs Checkout")
163 return KDevelop::VcsFileInfo::NeedsCheckout;
164 else
165 return KDevelop::VcsFileInfo::Unknown;
168 #include "cvsfileinfoprovider.moc"