diff --git a/projectbuilders/ninjabuilder/ninjajob.h b/projectbuilders/ninjabuilder/ninjajob.h --- a/projectbuilders/ninjabuilder/ninjajob.h +++ b/projectbuilders/ninjabuilder/ninjajob.h @@ -59,9 +59,6 @@ void emitProjectBuilderSignal(KJob* job); private: - /// Parse progress from ninja output - void parseProgress(const QString& line); - bool m_isInstalling; QPersistentModelIndex m_idx; QByteArray m_signal; diff --git a/projectbuilders/ninjabuilder/ninjajob.cpp b/projectbuilders/ninjabuilder/ninjajob.cpp --- a/projectbuilders/ninjabuilder/ninjajob.cpp +++ b/projectbuilders/ninjabuilder/ninjajob.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -37,18 +38,51 @@ #include #include +using namespace KDevelop; + +class NinjaJobCompilerFilterStrategy : public CompilerFilterStrategy +{ +public: + using CompilerFilterStrategy::CompilerFilterStrategy; + + IFilterStrategy::Progress progressInLine(const QString& line) override; +}; + +IFilterStrategy::Progress NinjaJobCompilerFilterStrategy::progressInLine(const QString& line) +{ + // example string: [87/88] Building CXX object projectbuilders/ninjabuilder/CMakeFiles/kdevninja.dir/ninjajob.cpp.o + static const QRegularExpression re("^\\[([0-9]+)\\/([0-9]+)\\] (.*)"); + + QRegularExpressionMatch match = re.match(line); + if (match.hasMatch()) { + const int current = match.captured(1).toInt(); + const int total = match.captured(2).toInt(); + if (current && total) { + // this is output from ninja + const QString action = match.captured(3); + const int percent = qRound((float)current / total * 100); + return {action, percent}; + } + } + + return {}; +} + NinjaJob::NinjaJob(KDevelop::ProjectBaseItem* item, const QStringList& arguments, const QByteArray& signal, KDevNinjaBuilderPlugin* parent) : OutputExecuteJob(parent) , m_isInstalling(false) , m_idx(item->index()) , m_signal(signal) , m_plugin(parent) { + auto bsm = item->project()->buildSystemManager(); + auto buildDir = bsm->buildDirectory(item); + setToolTitle(i18n("Ninja")); setCapabilities(Killable); setStandardToolView( KDevelop::IOutputView::BuildView ); setBehaviours(KDevelop::IOutputView::AllowUserClose | KDevelop::IOutputView::AutoScroll ); - setFilteringStrategy( KDevelop::OutputModel::CompilerFilter ); + setFilteringStrategy(new NinjaJobCompilerFilterStrategy(buildDir.toUrl())); setProperties( NeedWorkingDirectory | PortableMessages | DisplayStderr | IsBuilderHint | PostProcessOutput ); // hardcode the ninja output format so we can parse it reliably @@ -168,7 +202,6 @@ bool prev = false; for(QStringList::iterator it=ret.end(); it!=ret.begin(); ) { --it; - parseProgress(*it); bool curr = it->startsWith('['); if((prev && curr) || it->endsWith("] ")) it = ret.erase(it); @@ -182,27 +215,3 @@ { return KDevelop::ICore::self()->projectController()->projectModel()->itemFromIndex(m_idx); } - -void NinjaJob::parseProgress(const QString& line) -{ - // TODO: Probably more clever to move this into the output filtering (which is being performed in a separate thread) - // example string: [87/88] Building CXX object projectbuilders/ninjabuilder/CMakeFiles/kdevninja.dir/ninjajob.cpp.o - static const QRegularExpression re("^\\[([0-9]+)\\/([0-9]+)\\] (.*)"); - - QRegularExpressionMatch match = re.match(line); - if (match.hasMatch()) { - const int current = match.captured(1).toInt(); - const int total = match.captured(2).toInt(); - if (current && total) { - // this is output from ninja - emitPercent(current, total); - - if (current == total) { - emit infoMessage(this, i18n("Build finished")); - } else { - const QString action = match.captured(3); - emit infoMessage(this, action); - } - } - } -}