kde-extraapps/kdevelop/projectbuilders/ninjabuilder/ninjajob.cpp
2015-07-26 14:23:17 +03:00

170 lines
5.1 KiB
C++

/* This file is part of KDevelop
Copyright 2012 Aleix Pol Gonzalez <aleixpol@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "ninjajob.h"
#include <KProcess>
#include <KUrl>
#include <KDebug>
#include <KLocalizedString>
#include <KConfigGroup>
#include <KStandardDirs>
#include <interfaces/iproject.h>
#include <outputview/outputmodel.h>
#include <project/interfaces/ibuildsystemmanager.h>
#include <project/projectmodel.h>
#include <interfaces/iproject.h>
#include <interfaces/icore.h>
#include <interfaces/iprojectcontroller.h>
#include <QFile>
NinjaJob::NinjaJob(KDevelop::ProjectBaseItem* item, const QStringList& arguments, const QByteArray& signal, QObject* parent)
: OutputExecuteJob(parent)
, m_isInstalling(false)
, m_idx(item->index())
, m_signal(signal)
{
setToolTitle(i18n("Ninja"));
setCapabilities(Killable);
setStandardToolView( KDevelop::IOutputView::BuildView );
setBehaviours(KDevelop::IOutputView::AllowUserClose | KDevelop::IOutputView::AutoScroll );
setFilteringStrategy( KDevelop::OutputModel::CompilerFilter );
setProperties( NeedWorkingDirectory | PortableMessages | DisplayStderr | IsBuilderHint | PostProcessOutput );
*this << ninjaBinary();
*this << arguments;
QStringList targets;
foreach( const QString& arg, arguments ) {
if( !arg.startsWith( '-' ) ) {
targets << arg;
}
}
QString title;
if( !targets.isEmpty() )
title = i18n("Ninja (%1): %2", item->text(), targets.join(" "));
else
title = i18n("Ninja (%1)", item->text());
setJobName( title );
connect(this, SIGNAL(finished(KJob*)), SLOT(emitProjectBuilderSignal(KJob*)));
}
void NinjaJob::setIsInstalling( bool isInstalling )
{
m_isInstalling = isInstalling;
}
QString NinjaJob::ninjaBinary()
{
QString path = KStandardDirs::findExe("ninja-build");
if (path.isEmpty()) {
path = KStandardDirs::findExe("ninja");
}
return path;
}
KUrl NinjaJob::workingDirectory() const
{
KDevelop::ProjectBaseItem* it = item();
if(!it)
return KUrl();
KDevelop::IBuildSystemManager* bsm = it->project()->buildSystemManager();
KDevelop::Path workingDir = bsm->buildDirectory( it );
while( !QFile::exists( workingDir.toLocalFile() + "build.ninja" ) ) {
KDevelop::Path upWorkingDir = workingDir.parent();
if( !upWorkingDir.isValid() || upWorkingDir == workingDir ) {
return bsm->buildDirectory( it->project()->projectItem() ).toUrl();
}
workingDir = upWorkingDir;
}
return workingDir.toUrl();
}
QStringList NinjaJob::privilegedExecutionCommand() const
{
KDevelop::ProjectBaseItem* it = item();
if(!it)
return QStringList();
KSharedConfig::Ptr configPtr = it->project()->projectConfiguration();
KConfigGroup builderGroup( configPtr, "NinjaBuilder" );
bool runAsRoot = builderGroup.readEntry( "Install As Root", false );
if ( runAsRoot && m_isInstalling )
{
int suCommand = builderGroup.readEntry( "Su Command", 0 );
QStringList arguments;
QString suCommandName;
switch( suCommand ) {
case 1:
return QStringList() << "kdesudo" << "-t";
case 2:
return QStringList() << "sudo";
default:
return QStringList() << "kdesu" << "-t";
}
}
return QStringList();
}
void NinjaJob::emitProjectBuilderSignal(KJob* job)
{
Q_ASSERT(!m_signal.isEmpty());
KDevelop::ProjectBaseItem* it = item();
if(!it)
return;
if(job->error()==0)
QMetaObject::invokeMethod(parent(), m_signal, Q_ARG(KDevelop::ProjectBaseItem*, it));
else
QMetaObject::invokeMethod(parent(), "failed", Q_ARG(KDevelop::ProjectBaseItem*, it));
}
void NinjaJob::postProcessStderr( const QStringList& lines )
{
appendLines( lines );
}
void NinjaJob::postProcessStdout( const QStringList& lines )
{
appendLines( lines );
}
void NinjaJob::appendLines(const QStringList& lines)
{
if(lines.isEmpty())
return;
QStringList ret(lines);
bool prev = false;
for(QStringList::iterator it=ret.end(); it!=ret.begin(); ) {
--it;
bool curr = it->startsWith('[');
if((prev && curr) || it->endsWith("] "))
it = ret.erase(it);
prev = curr;
}
model()->appendLines(ret);
}
KDevelop::ProjectBaseItem* NinjaJob::item() const
{
return KDevelop::ICore::self()->projectController()->projectModel()->itemFromIndex(m_idx);
}