File indexing completed on 2024-05-05 16:41:34

0001 /*
0002     SPDX-FileCopyrightText: 2012 Sven Brauch <svenbrauch@googlemail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "pdblauncher.h"
0008 #include <interfaces/idocumentcontroller.h>
0009 #include "debugjob.h"
0010 
0011 #include <util/executecompositejob.h>
0012 #include <executescript/iexecutescriptplugin.h>
0013 #include <interfaces/launchconfigurationpage.h>
0014 #include <interfaces/ilaunchconfiguration.h>
0015 #include <interfaces/iplugincontroller.h>
0016 #include <interfaces/iruncontroller.h>
0017 #include <interfaces/icore.h>
0018 #include <interfaces/iuicontroller.h>
0019 
0020 #include <KLocalizedString>
0021 #include <KMessageBox>
0022 #include <KParts/MainWindow>
0023 #include <KConfigGroup>
0024 #include <QFileInfo>
0025 
0026 #include <QDebug>
0027 #include "debuggerdebug.h"
0028 #include <util/environmentprofilelist.h>
0029 
0030 
0031 namespace Python {
0032     
0033 PdbLauncher::PdbLauncher()
0034 {
0035 
0036 }
0037 
0038 QList< KDevelop::LaunchConfigurationPageFactory* > PdbLauncher::configPages() const
0039 {
0040     return QList<KDevelop::LaunchConfigurationPageFactory*>();
0041 }
0042 
0043 QString PdbLauncher::description() const
0044 {
0045     return i18n("A plugin to debug Python applications with pdb.");
0046 }
0047 
0048 QString PdbLauncher::id()
0049 {
0050     return "pdbdebugger";
0051 }
0052 
0053 QString PdbLauncher::name() const
0054 {
0055     return "pdbdebugger";
0056 }
0057 
0058 KJob* PdbLauncher::start(const QString& launchMode, KDevelop::ILaunchConfiguration* cfg)
0059 {
0060     qCDebug(KDEV_PYTHON_DEBUGGER) << "start of debugger process requested";
0061     if ( launchMode == "debug" ) {
0062         IExecuteScriptPlugin* iface = KDevelop::ICore::self()->pluginController()
0063                                       ->pluginForExtension("org.kdevelop.IExecuteScriptPlugin")->extension<IExecuteScriptPlugin>();
0064         Q_ASSERT(iface);
0065         QString err;
0066         QString interpreter = iface->interpreter(cfg, err);
0067         
0068         // check the interpreter
0069         QProcess p;
0070         p.setProcessChannelMode(QProcess::MergedChannels);
0071         p.start(interpreter, QStringList() << "--version");
0072         p.waitForFinished(500);
0073         QByteArray version = p.readAll();
0074         qCDebug(KDEV_PYTHON_DEBUGGER) << "interpreter version:" << version;
0075         if ( ! version.startsWith("Python 3.") ) {
0076             KMessageBox::error(ICore::self()->uiController()->activeMainWindow(),
0077                             i18n("Sorry, debugging is only supported for Python 3.x applications."),
0078                             i18n("Unsupported interpreter"));
0079             return nullptr;
0080         }
0081 
0082         QUrl scriptUrl;
0083         if ( iface->runCurrentFile(cfg) ) {
0084             auto document = KDevelop::ICore::self()->documentController()->activeDocument();
0085             if ( ! document ) {
0086                 qCDebug(KDEV_PYTHON_DEBUGGER) << "no current document";
0087                 return nullptr;
0088             }
0089             scriptUrl = document->url();
0090         }
0091         else {
0092             scriptUrl = iface->script(cfg, err);
0093         }
0094 
0095         auto wd = iface->workingDirectory(cfg);
0096         if( !wd.isValid() || wd.isEmpty() )
0097         {
0098             wd = QUrl::fromLocalFile( QFileInfo( scriptUrl.toLocalFile() ).absolutePath() );
0099         }
0100 
0101         DebugJob* job = new DebugJob();
0102         job->m_scriptUrl = scriptUrl;
0103         job->m_interpreter = interpreter;
0104         job->m_args = iface->arguments(cfg, err);
0105         job->m_workingDirectory = wd;
0106 
0107         const KDevelop::EnvironmentProfileList environmentProfiles(KSharedConfig::openConfig());
0108         QString envProfileName = iface->environmentProfileName(cfg);
0109 
0110         if (envProfileName.isEmpty()) {
0111             qCWarning(KDEV_PYTHON_DEBUGGER) << "No environment profile specified, looks like a broken "
0112                                        "configuration, please check run configuration " << cfg->name() <<
0113                                        ". Using default environment profile.";
0114             envProfileName = environmentProfiles.defaultProfileName();
0115         }
0116         job->m_envProfileName = envProfileName;
0117 
0118         QList<KJob*> l;
0119         l << job;
0120         return new KDevelop::ExecuteCompositeJob( KDevelop::ICore::self()->runController(), l );
0121     }
0122     qCDebug(KDEV_PYTHON_DEBUGGER) << "unknown launch mode";
0123     return nullptr;
0124 }
0125 
0126 QStringList PdbLauncher::supportedModes() const
0127 {
0128     return QStringList() << "debug";
0129 }
0130 
0131 }