File indexing completed on 2024-04-28 04:38:38
0001 /* 0002 SPDX-FileCopyrightText: 2007 Hamish Rodda <rodda@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "executeplugin.h" 0008 0009 #include <KConfigGroup> 0010 #include <KJob> 0011 #include <KLocalizedString> 0012 #include <KParts/MainWindow> 0013 #include <KPluginFactory> 0014 #include <KShell> 0015 0016 #include <interfaces/icore.h> 0017 #include <interfaces/iruncontroller.h> 0018 #include <interfaces/ilaunchconfiguration.h> 0019 #include <interfaces/iprojectcontroller.h> 0020 #include <interfaces/iuicontroller.h> 0021 #include <sublime/message.h> 0022 0023 #include "nativeappconfig.h" 0024 #include "debug.h" 0025 #include <project/projectmodel.h> 0026 #include <project/builderjob.h> 0027 #include <util/kdevstringhandler.h> 0028 0029 using namespace KDevelop; 0030 0031 K_PLUGIN_FACTORY_WITH_JSON(KDevExecuteFactory, "kdevexecute.json", registerPlugin<ExecutePlugin>();) 0032 0033 ExecutePlugin::ExecutePlugin(QObject *parent, const QVariantList&) 0034 : KDevelop::IPlugin(QStringLiteral("kdevexecute"), parent) 0035 { 0036 m_configType = new NativeAppConfigType(); 0037 m_configType->addLauncher( new NativeAppLauncher() ); 0038 qCDebug(PLUGIN_EXECUTE) << "adding native app launch config"; 0039 core()->runController()->addConfigurationType( m_configType ); 0040 } 0041 0042 ExecutePlugin::~ExecutePlugin() 0043 { 0044 } 0045 0046 void ExecutePlugin::unload() 0047 { 0048 core()->runController()->removeConfigurationType( m_configType ); 0049 delete m_configType; 0050 m_configType = nullptr; 0051 } 0052 0053 QStringList ExecutePlugin::arguments( KDevelop::ILaunchConfiguration* cfg, QString& err_ ) const 0054 { 0055 0056 if( !cfg ) 0057 { 0058 return QStringList(); 0059 } 0060 0061 KShell::Errors err; 0062 QStringList args = KShell::splitArgs( cfg->config().readEntry( ExecutePlugin::argumentsEntry, "" ), KShell::TildeExpand | KShell::AbortOnMeta, &err ); 0063 if( err != KShell::NoError ) 0064 { 0065 0066 if( err == KShell::BadQuoting ) 0067 { 0068 err_ = i18n("There is a quoting error in the arguments for " 0069 "the launch configuration '%1'. Aborting start.", cfg->name() ); 0070 } else 0071 { 0072 err_ = i18n("A shell meta character was included in the " 0073 "arguments for the launch configuration '%1', " 0074 "this is not supported currently. Aborting start.", cfg->name() ); 0075 } 0076 args = QStringList(); 0077 qCWarning(PLUGIN_EXECUTE) << "Launch Configuration:" << cfg->name() << "arguments have meta characters"; 0078 } 0079 return args; 0080 } 0081 0082 0083 KJob* ExecutePlugin::dependencyJob( KDevelop::ILaunchConfiguration* cfg ) const 0084 { 0085 const QVariantList deps = KDevelop::stringToQVariant( cfg->config().readEntry( dependencyEntry, QString() ) ).toList(); 0086 QString depAction = cfg->config().readEntry( dependencyActionEntry, "Nothing" ); 0087 if( depAction != QLatin1String("Nothing") && !deps.isEmpty() ) 0088 { 0089 KDevelop::ProjectModel* model = KDevelop::ICore::self()->projectController()->projectModel(); 0090 QList<KDevelop::ProjectBaseItem*> items; 0091 for (const QVariant& dep : deps) { 0092 KDevelop::ProjectBaseItem* item = model->itemFromIndex( model->pathToIndex( dep.toStringList() ) ); 0093 if( item ) 0094 { 0095 items << item; 0096 } 0097 else 0098 { 0099 const QString messageText = i18n("Couldn't resolve the dependency: %1", dep.toString()); 0100 auto* message = new Sublime::Message(messageText, Sublime::Message::Error); 0101 ICore::self()->uiController()->postMessage(message); 0102 } 0103 } 0104 auto* job = new KDevelop::BuilderJob(); 0105 if( depAction == QLatin1String("Build") ) 0106 { 0107 job->addItems( KDevelop::BuilderJob::Build, items ); 0108 } else if( depAction == QLatin1String("Install") ) 0109 { 0110 job->addItems( KDevelop::BuilderJob::Install, items ); 0111 } 0112 job->updateJobName(); 0113 return job; 0114 } 0115 return nullptr; 0116 } 0117 0118 0119 QString ExecutePlugin::environmentProfileName(KDevelop::ILaunchConfiguration* cfg) const 0120 { 0121 if( !cfg ) 0122 { 0123 return QString(); 0124 } 0125 0126 return cfg->config().readEntry(ExecutePlugin::environmentProfileEntry, QString()); 0127 } 0128 0129 0130 QUrl ExecutePlugin::executable( KDevelop::ILaunchConfiguration* cfg, QString& err ) const 0131 { 0132 QUrl executable; 0133 if( !cfg ) 0134 { 0135 return executable; 0136 } 0137 KConfigGroup grp = cfg->config(); 0138 if( grp.readEntry(ExecutePlugin::isExecutableEntry, false ) ) 0139 { 0140 executable = grp.readEntry( ExecutePlugin::executableEntry, QUrl() ); 0141 } else 0142 { 0143 QStringList prjitem = grp.readEntry( ExecutePlugin::projectTargetEntry, QStringList() ); 0144 KDevelop::ProjectModel* model = KDevelop::ICore::self()->projectController()->projectModel(); 0145 KDevelop::ProjectBaseItem* item = model->itemFromIndex( model->pathToIndex(prjitem) ); 0146 if( item && item->executable() ) 0147 { 0148 // TODO: Need an option in the gui to choose between installed and builddir url here, currently cmake only supports builddir url 0149 executable = item->executable()->builtUrl(); 0150 } 0151 } 0152 if( executable.isEmpty() ) 0153 { 0154 err = i18n("No valid executable specified"); 0155 qCWarning(PLUGIN_EXECUTE) << "Launch Configuration:" << cfg->name() << "no valid executable set"; 0156 } else 0157 { 0158 KShell::Errors err_; 0159 if( KShell::splitArgs( executable.toLocalFile(), KShell::TildeExpand | KShell::AbortOnMeta, &err_ ).isEmpty() || err_ != KShell::NoError ) 0160 { 0161 executable = QUrl(); 0162 if( err_ == KShell::BadQuoting ) 0163 { 0164 err = i18n("There is a quoting error in the executable " 0165 "for the launch configuration '%1'. " 0166 "Aborting start.", cfg->name() ); 0167 } else 0168 { 0169 err = i18n("A shell meta character was included in the " 0170 "executable for the launch configuration '%1', " 0171 "this is not supported currently. Aborting start.", cfg->name() ); 0172 } 0173 qCWarning(PLUGIN_EXECUTE) << "Launch Configuration:" << cfg->name() << "executable has meta characters"; 0174 } 0175 } 0176 return executable; 0177 } 0178 0179 0180 bool ExecutePlugin::useTerminal( KDevelop::ILaunchConfiguration* cfg ) const 0181 { 0182 if( !cfg ) 0183 { 0184 return false; 0185 } 0186 0187 return cfg->config().readEntry( ExecutePlugin::useTerminalEntry, false ); 0188 } 0189 0190 0191 QString ExecutePlugin::terminal( KDevelop::ILaunchConfiguration* cfg ) const 0192 { 0193 if( !cfg ) 0194 { 0195 return QString(); 0196 } 0197 0198 return cfg->config().readEntry( ExecutePlugin::terminalEntry, QString() ); 0199 } 0200 0201 0202 QUrl ExecutePlugin::workingDirectory( KDevelop::ILaunchConfiguration* cfg ) const 0203 { 0204 if( !cfg ) 0205 { 0206 return QUrl(); 0207 } 0208 0209 return cfg->config().readEntry( ExecutePlugin::workingDirEntry, QUrl() ); 0210 } 0211 0212 0213 QString ExecutePlugin::nativeAppConfigTypeId() const 0214 { 0215 return NativeAppConfigType::sharedId(); 0216 } 0217 0218 0219 #include "executeplugin.moc" 0220 #include "moc_executeplugin.cpp"