forked from qt-creator/qt-creator
Python: add pyside build configuration
Task-number: QTCREATORBUG-27219 Change-Id: I19340c57789933c7104ec5d6fec628ed810c5f3e Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -807,6 +807,13 @@ void InterpreterAspect::updateInterpreters(const QList<Interpreter> &interpreter
|
||||
updateComboBox();
|
||||
}
|
||||
|
||||
void InterpreterAspect::setDefaultInterpreter(const Interpreter &interpreter)
|
||||
{
|
||||
m_defaultId = interpreter.id;
|
||||
if (m_currentId.isEmpty())
|
||||
m_currentId = m_defaultId;
|
||||
}
|
||||
|
||||
void InterpreterAspect::setCurrentInterpreter(const Interpreter &interpreter)
|
||||
{
|
||||
m_currentId = interpreter.id;
|
||||
@@ -820,6 +827,7 @@ void InterpreterAspect::fromMap(const QVariantMap &map)
|
||||
|
||||
void InterpreterAspect::toMap(QVariantMap &map) const
|
||||
{
|
||||
if (m_currentId != m_defaultId)
|
||||
saveToMap(map, m_currentId, QString(), settingsKey());
|
||||
}
|
||||
|
||||
|
@@ -244,7 +244,7 @@ public:
|
||||
|
||||
Interpreter currentInterpreter() const;
|
||||
void updateInterpreters(const QList<Interpreter> &interpreters);
|
||||
void setDefaultInterpreter(const Interpreter &interpreter) { m_defaultId = interpreter.id; }
|
||||
void setDefaultInterpreter(const Interpreter &interpreter);
|
||||
void setCurrentInterpreter(const Interpreter &interpreter);
|
||||
void setSettingsDialogId(Utils::Id id) { m_settingsDialogId = id; }
|
||||
|
||||
|
@@ -4,6 +4,7 @@ add_qtc_plugin(Python
|
||||
SOURCES
|
||||
pipsupport.cpp pipsupport.h
|
||||
pyside.cpp pyside.h
|
||||
pysidebuildconfiguration.cpp pysidebuildconfiguration.h
|
||||
python.qrc
|
||||
pythonconstants.h
|
||||
pythoneditor.cpp pythoneditor.h
|
||||
|
134
src/plugins/python/pysidebuildconfiguration.cpp
Normal file
134
src/plugins/python/pysidebuildconfiguration.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "pysidebuildconfiguration.h"
|
||||
|
||||
#include "pipsupport.h"
|
||||
#include "pythonconstants.h"
|
||||
#include "pythonproject.h"
|
||||
#include "pythonrunconfiguration.h"
|
||||
#include "pythonsettings.h"
|
||||
|
||||
#include <projectexplorer/buildinfo.h>
|
||||
#include <projectexplorer/buildsteplist.h>
|
||||
#include <projectexplorer/environmentaspect.h>
|
||||
#include <projectexplorer/processparameters.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <utils/commandline.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
namespace Python {
|
||||
namespace Internal {
|
||||
|
||||
constexpr char pySideBuildStep[] = "Python.PysideBuildStep";
|
||||
|
||||
PySideBuildConfigurationFactory::PySideBuildConfigurationFactory()
|
||||
{
|
||||
registerBuildConfiguration<PySideBuildConfiguration>("Python.PySideBuildConfiguration");
|
||||
setSupportedProjectType(PythonProjectId);
|
||||
setSupportedProjectMimeTypeName(Constants::C_PY_MIMETYPE);
|
||||
setBuildGenerator([](const Kit *, const FilePath &projectPath, bool) {
|
||||
BuildInfo info;
|
||||
info.displayName = "build";
|
||||
info.typeName = "build";
|
||||
info.buildDirectory = projectPath.parentDir();
|
||||
return QList<BuildInfo>{info};
|
||||
});
|
||||
}
|
||||
|
||||
PySideBuildStepFactory::PySideBuildStepFactory()
|
||||
{
|
||||
registerStep<PySideBuildStep>(pySideBuildStep);
|
||||
setSupportedProjectType(PythonProjectId);
|
||||
setDisplayName(tr("Run PySide6 project tool"));
|
||||
setFlags(BuildStepInfo::UniqueStep);
|
||||
}
|
||||
|
||||
PySideBuildStep::PySideBuildStep(BuildStepList *bsl, Id id)
|
||||
: AbstractProcessStep(bsl, id)
|
||||
{
|
||||
m_pysideProject = addAspect<StringAspect>();
|
||||
m_pysideProject->setSettingsKey("Python.PySideProjectTool");
|
||||
m_pysideProject->setLabelText(tr("PySide project tool:"));
|
||||
m_pysideProject->setToolTip(tr("Enter location of PySide project tool."));
|
||||
m_pysideProject->setDisplayStyle(StringAspect::PathChooserDisplay);
|
||||
m_pysideProject->setExpectedKind(PathChooser::Command);
|
||||
m_pysideProject->setHistoryCompleter("Python.PySideProjectTool.History");
|
||||
|
||||
const FilePath pySideProjectPath = Environment::systemEnvironment().searchInPath(
|
||||
"pyside6-project");
|
||||
if (pySideProjectPath.isExecutableFile())
|
||||
m_pysideProject->setFilePath(pySideProjectPath);
|
||||
|
||||
setCommandLineProvider([this] { return CommandLine(m_pysideProject->filePath(), {"build"}); });
|
||||
setWorkingDirectoryProvider([this] { return target()->project()->projectDirectory(); });
|
||||
}
|
||||
|
||||
void PySideBuildStep::updateInterpreter(const Utils::FilePath &python)
|
||||
{
|
||||
Utils::FilePath pySideProjectPath;
|
||||
const PipPackage pySide6Package("PySide6");
|
||||
const PipPackageInfo info = pySide6Package.info(python);
|
||||
for (const FilePath &file : qAsConst(info.files)) {
|
||||
if (file.fileName() == HostOsInfo::withExecutableSuffix("pyside6-project")) {
|
||||
pySideProjectPath = info.location.resolvePath(file);
|
||||
pySideProjectPath = pySideProjectPath.cleanPath();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pySideProjectPath.isExecutableFile())
|
||||
pySideProjectPath = Environment::systemEnvironment().searchInPath("pyside6-project");
|
||||
|
||||
if (pySideProjectPath.isExecutableFile())
|
||||
m_pysideProject->setFilePath(pySideProjectPath);
|
||||
}
|
||||
|
||||
void PySideBuildStep::doRun()
|
||||
{
|
||||
if (processParameters()->effectiveCommand().isExecutableFile())
|
||||
AbstractProcessStep::doRun();
|
||||
else
|
||||
emit finished(true);
|
||||
}
|
||||
|
||||
PySideBuildConfiguration::PySideBuildConfiguration(Target *target, Id id)
|
||||
: BuildConfiguration(target, id)
|
||||
{
|
||||
setConfigWidgetDisplayName(tr("General"));
|
||||
|
||||
setInitializer([this](const BuildInfo &) {
|
||||
buildSteps()->appendStep(pySideBuildStep);
|
||||
updateCacheAndEmitEnvironmentChanged();
|
||||
});
|
||||
|
||||
updateCacheAndEmitEnvironmentChanged();
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Python
|
70
src/plugins/python/pysidebuildconfiguration.h
Normal file
70
src/plugins/python/pysidebuildconfiguration.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <projectexplorer/abstractprocessstep.h>
|
||||
#include <projectexplorer/buildconfiguration.h>
|
||||
#include <projectexplorer/buildstep.h>
|
||||
|
||||
namespace Python {
|
||||
namespace Internal {
|
||||
|
||||
class PySideBuildConfiguration : public ProjectExplorer::BuildConfiguration
|
||||
{
|
||||
public:
|
||||
PySideBuildConfiguration(ProjectExplorer::Target *target, Utils::Id id);
|
||||
};
|
||||
|
||||
class PySideBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationFactory
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Python::Internal::PySideBuildConfigurationFactory)
|
||||
public:
|
||||
PySideBuildConfigurationFactory();
|
||||
};
|
||||
|
||||
class PySideBuildStep : public ProjectExplorer::AbstractProcessStep
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PySideBuildStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id);
|
||||
void updateInterpreter(const Utils::FilePath &python);
|
||||
|
||||
private:
|
||||
Utils::StringAspect *m_pysideProject;
|
||||
|
||||
private:
|
||||
void doRun() override;
|
||||
};
|
||||
|
||||
class PySideBuildStepFactory : public ProjectExplorer::BuildStepFactory
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Python::Internal::PySideBuildStepFactory)
|
||||
public:
|
||||
PySideBuildStepFactory();
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Python
|
@@ -21,6 +21,8 @@ QtcPlugin {
|
||||
"pipsupport.h",
|
||||
"pyside.cpp",
|
||||
"pyside.h",
|
||||
"pysidebuildconfiguration.cpp",
|
||||
"pysidebuildconfiguration.h",
|
||||
"python.qrc",
|
||||
"pythonconstants.h",
|
||||
"pythoneditor.cpp",
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "pythonplugin.h"
|
||||
|
||||
#include "pysidebuildconfiguration.h"
|
||||
#include "pythonconstants.h"
|
||||
#include "pythoneditor.h"
|
||||
#include "pythonlanguageclient.h"
|
||||
@@ -61,6 +62,8 @@ public:
|
||||
PythonEditorFactory editorFactory;
|
||||
PythonOutputFormatterFactory outputFormatterFactory;
|
||||
PythonRunConfigurationFactory runConfigFactory;
|
||||
PySideBuildStepFactory buildStepFactory;
|
||||
PySideBuildConfigurationFactory buildConfigFactory;
|
||||
|
||||
RunWorkerFactory runWorkerFactory{
|
||||
RunWorkerFactory::make<SimpleTargetRunner>(),
|
||||
|
@@ -220,7 +220,6 @@ PythonProject::PythonProject(const FilePath &fileName)
|
||||
setProjectLanguages(Context(ProjectExplorer::Constants::PYTHON_LANGUAGE_ID));
|
||||
setDisplayName(fileName.completeBaseName());
|
||||
|
||||
setNeedsBuildConfigurations(false);
|
||||
setBuildSystemCreator([](Target *t) { return new PythonBuildSystem(t); });
|
||||
}
|
||||
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include "pythonrunconfiguration.h"
|
||||
|
||||
#include "pyside.h"
|
||||
#include "pysidebuildconfiguration.h"
|
||||
#include "pythonconstants.h"
|
||||
#include "pythonlanguageclient.h"
|
||||
#include "pythonproject.h"
|
||||
@@ -36,6 +37,7 @@
|
||||
|
||||
#include <languageclient/languageclientmanager.h>
|
||||
|
||||
#include <projectexplorer/buildsteplist.h>
|
||||
#include <projectexplorer/buildsystem.h>
|
||||
#include <projectexplorer/localenvironmentaspect.h>
|
||||
#include <projectexplorer/runconfigurationaspects.h>
|
||||
@@ -145,27 +147,21 @@ public:
|
||||
interpreterAspect->setSettingsKey("PythonEditor.RunConfiguation.Interpreter");
|
||||
interpreterAspect->setSettingsDialogId(Constants::C_PYTHONOPTIONS_PAGE_ID);
|
||||
|
||||
connect(interpreterAspect, &InterpreterAspect::changed, this, [this, interpreterAspect] {
|
||||
using namespace LanguageClient;
|
||||
const FilePath python = interpreterAspect->currentInterpreter().command;
|
||||
|
||||
for (FilePath &file : project()->files(Project::AllFiles)) {
|
||||
if (auto document = TextEditor::TextDocument::textDocumentForFilePath(file)) {
|
||||
if (document->mimeType() == Constants::C_PY_MIMETYPE) {
|
||||
PyLSConfigureAssistant::openDocumentWithPython(python, document);
|
||||
PySideInstaller::checkPySideInstallation(python, document);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(interpreterAspect, &InterpreterAspect::changed,
|
||||
this, &PythonRunConfiguration::currentInterpreterChanged);
|
||||
|
||||
connect(PythonSettings::instance(), &PythonSettings::interpretersChanged,
|
||||
interpreterAspect, &InterpreterAspect::updateInterpreters);
|
||||
|
||||
QList<Interpreter> interpreters = PythonSettings::detectPythonVenvs(project()->projectDirectory());
|
||||
QList<Interpreter> interpreters = PythonSettings::detectPythonVenvs(
|
||||
project()->projectDirectory());
|
||||
interpreterAspect->updateInterpreters(PythonSettings::interpreters());
|
||||
interpreterAspect->setDefaultInterpreter(
|
||||
interpreters.isEmpty() ? PythonSettings::defaultInterpreter() : interpreters.first());
|
||||
Interpreter defaultInterpreter = interpreters.isEmpty()
|
||||
? PythonSettings::defaultInterpreter()
|
||||
: interpreters.first();
|
||||
if (!defaultInterpreter.command.isExecutableFile())
|
||||
defaultInterpreter = PythonSettings::interpreters().value(0);
|
||||
interpreterAspect->setDefaultInterpreter(defaultInterpreter);
|
||||
|
||||
auto bufferedAspect = addAspect<BoolAspect>();
|
||||
bufferedAspect->setSettingsKey("PythonEditor.RunConfiguation.Buffered");
|
||||
@@ -204,6 +200,24 @@ public:
|
||||
|
||||
connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update);
|
||||
}
|
||||
|
||||
void currentInterpreterChanged()
|
||||
{
|
||||
const FilePath python = aspect<InterpreterAspect>()->currentInterpreter().command;
|
||||
|
||||
BuildStepList *buildSteps = target()->activeBuildConfiguration()->buildSteps();
|
||||
if (auto pySideBuildStep = buildSteps->firstOfType<PySideBuildStep>())
|
||||
pySideBuildStep->updateInterpreter(python);
|
||||
|
||||
for (FilePath &file : project()->files(Project::AllFiles)) {
|
||||
if (auto document = TextEditor::TextDocument::textDocumentForFilePath(file)) {
|
||||
if (document->mimeType() == Constants::C_PY_MIMETYPE) {
|
||||
PyLSConfigureAssistant::openDocumentWithPython(python, document);
|
||||
PySideInstaller::checkPySideInstallation(python, document);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PythonRunConfigurationFactory::PythonRunConfigurationFactory()
|
||||
|
Reference in New Issue
Block a user