File indexing completed on 2024-05-19 04:41:21
0001 /* 0002 SPDX-FileCopyrightText: 2019 Daniel Mensinger <daniel@mensinger-ka.de> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "mesonrewriterjob.h" 0008 #include "mesonconfig.h" 0009 0010 #include "interfaces/iproject.h" 0011 #include "util/path.h" 0012 0013 #include <KLocalizedString> 0014 #include <KProcess> 0015 #include <QJsonArray> 0016 #include <QJsonDocument> 0017 #include <QTemporaryFile> 0018 #include <QtConcurrentRun> 0019 0020 #include "debug.h" 0021 0022 using namespace KDevelop; 0023 0024 MesonRewriterJob::MesonRewriterJob(IProject* project, const QVector<MesonRewriterActionPtr>& actions, QObject* parent) 0025 : KJob(parent) 0026 , m_project(project) 0027 , m_actions(actions) 0028 { 0029 connect(&m_futureWatcher, &QFutureWatcher<QString>::finished, this, &MesonRewriterJob::finished); 0030 } 0031 0032 QString MesonRewriterJob::execute() 0033 { 0034 QJsonArray command; 0035 for (auto& i : m_actions) { 0036 command.append(i->command()); 0037 } 0038 0039 QTemporaryFile tempFile; 0040 tempFile.setAutoRemove(false); 0041 if (!tempFile.open()) { 0042 return i18n("Failed to create a temporary file."); 0043 } 0044 0045 QJsonDocument doc(command); 0046 tempFile.write(doc.toJson()); 0047 tempFile.flush(); 0048 0049 Meson::BuildDir buildDir = Meson::currentBuildDir(m_project); 0050 0051 KProcess proc(this); 0052 proc.setWorkingDirectory(m_project->path().toLocalFile()); 0053 proc.setOutputChannelMode(KProcess::SeparateChannels); 0054 proc.setProgram(buildDir.mesonExecutable.toLocalFile()); 0055 proc << QStringLiteral("rewrite") << QStringLiteral("command") << tempFile.fileName(); 0056 0057 int ret = proc.execute(); 0058 if (ret != 0) { 0059 return i18n("%1 returned %2", proc.program().join(QLatin1Char(' ')), ret); 0060 } 0061 0062 auto rawData = proc.readAllStandardError(); 0063 if (rawData.isEmpty()) { 0064 return QString(); 0065 } 0066 0067 QJsonParseError error; 0068 QJsonDocument result = QJsonDocument::fromJson(rawData, &error); 0069 if (error.error) { 0070 return i18n("JSON parser error: %1", error.errorString()); 0071 } 0072 0073 if (!result.isObject()) { 0074 return i18n("The rewriter output of '%1' is not an object", proc.program().join(QLatin1Char(' '))); 0075 } 0076 0077 for (auto& i : m_actions) { 0078 i->parseResult(result.object()); 0079 } 0080 0081 return QString(); 0082 } 0083 0084 void MesonRewriterJob::finished() 0085 { 0086 QString result = m_futureWatcher.result(); 0087 if (!result.isEmpty()) { 0088 qCWarning(KDEV_Meson) << "REWRITER " << result; 0089 setError(true); 0090 setErrorText(result); 0091 emitResult(); 0092 return; 0093 } 0094 0095 qCDebug(KDEV_Meson) << "REWRITER: Meson rewriter job finished"; 0096 emitResult(); 0097 } 0098 0099 bool MesonRewriterJob::doKill() 0100 { 0101 if (m_futureWatcher.isRunning()) { 0102 m_futureWatcher.cancel(); 0103 } 0104 return true; 0105 } 0106 0107 void MesonRewriterJob::start() 0108 { 0109 auto future = QtConcurrent::run(this, &MesonRewriterJob::execute); 0110 m_futureWatcher.setFuture(future); 0111 } 0112 0113 #include "moc_mesonrewriterjob.cpp"