ui: check validity of Python environment when entered in Python Source Group
* Python sourcegroup now displays if a provided Python environment is valid * update used version of SourcetrailPythonIndexer * changed executeProcess() to return the process' exit code and console output
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
SOURCETRAIL_PYTHON_INDEXER_VERSION="v0_db24_p1"
|
||||
SOURCETRAIL_PYTHON_INDEXER_VERSION="v1_db24_p0"
|
||||
|
||||
# Determine current platform
|
||||
PLATFORM='unknown'
|
||||
|
||||
@@ -25,6 +25,7 @@ QtLocationPicker::QtLocationPicker(QWidget *parent)
|
||||
m_data = new QtLineEdit(this);
|
||||
m_data->setAttribute(Qt::WA_MacShowFocusRect, 0);
|
||||
m_data->setObjectName("locationField");
|
||||
connect(m_data, &QtLineEdit::textChanged, this, &QtLocationPicker::onDataTextChanged);
|
||||
layout->addWidget(m_data);
|
||||
|
||||
m_button = new QtIconButton(
|
||||
@@ -34,7 +35,7 @@ QtLocationPicker::QtLocationPicker(QWidget *parent)
|
||||
m_button->setIconSize(QSize(16, 16));
|
||||
m_button->setObjectName("dotsButton");
|
||||
m_button->setToolTip("pick file");
|
||||
connect(m_button, &QPushButton::clicked, this, &QtLocationPicker::handleButtonPress);
|
||||
connect(m_button, &QPushButton::clicked, this, &QtLocationPicker::onHandleButtonPressed);
|
||||
layout->addWidget(m_button);
|
||||
|
||||
setLayout(layout);
|
||||
@@ -98,7 +99,7 @@ void QtLocationPicker::changeEvent(QEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
void QtLocationPicker::handleButtonPress()
|
||||
void QtLocationPicker::onHandleButtonPressed()
|
||||
{
|
||||
FilePath path(m_data->text().toStdWString());
|
||||
if (!path.empty() && !path.isAbsolute() && !m_relativeRootDirectory.empty())
|
||||
@@ -124,3 +125,8 @@ void QtLocationPicker::handleButtonPress()
|
||||
emit locationPicked();
|
||||
}
|
||||
}
|
||||
|
||||
void QtLocationPicker::onDataTextChanged(const QString& text)
|
||||
{
|
||||
emit textChanged(text);
|
||||
}
|
||||
|
||||
@@ -30,14 +30,15 @@ public:
|
||||
|
||||
signals:
|
||||
void locationPicked();
|
||||
void textChanged(const QString& text);
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void handleButtonPress();
|
||||
|
||||
private:
|
||||
void onHandleButtonPressed();
|
||||
void onDataTextChanged(const QString& text);
|
||||
|
||||
QPushButton* m_button;
|
||||
QtLineEdit* m_data;
|
||||
|
||||
|
||||
@@ -6,16 +6,22 @@
|
||||
#include <QMessageBox>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Application.h"
|
||||
#include "ApplicationSettings.h"
|
||||
#include "FileManager.h"
|
||||
#include "MessageStatus.h"
|
||||
#include "QtLocationPicker.h"
|
||||
#include "QtDialogView.h"
|
||||
#include "QtProjectWizzardContentPaths.h"
|
||||
#include "ResourcePaths.h"
|
||||
#include "ScopedFunctor.h"
|
||||
#include "SonargraphProject.h"
|
||||
#include "SourceGroupCxxCdb.h"
|
||||
#include "SourceGroupCxxCodeblocks.h"
|
||||
#include "SourceGroupCxxSonargraph.h"
|
||||
#include "SourceGroupJavaSonargraph.h"
|
||||
#include "SourceGroupJavaGradle.h"
|
||||
#include "SourceGroupJavaMaven.h"
|
||||
#include "QtLocationPicker.h"
|
||||
#include "QtDialogView.h"
|
||||
#include "QtProjectWizzardContentPaths.h"
|
||||
#include "ApplicationSettings.h"
|
||||
#include "SourceGroupSettingsCxxCdb.h"
|
||||
#include "SourceGroupSettingsCxxCodeblocks.h"
|
||||
#include "SourceGroupSettingsCxxSonargraph.h"
|
||||
@@ -24,15 +30,11 @@
|
||||
#include "SourceGroupSettingsJavaSonargraph.h"
|
||||
#include "SourceGroupSettingsPythonEmpty.h"
|
||||
#include "SourceGroupSettingsWithSonargraphProjectPath.h"
|
||||
#include "FileManager.h"
|
||||
#include "MessageStatus.h"
|
||||
#include "SonargraphProject.h"
|
||||
#include "ScopedFunctor.h"
|
||||
#include "utility.h"
|
||||
#include "utilityApp.h"
|
||||
#include "utilityFile.h"
|
||||
#include "utilityGradle.h"
|
||||
#include "utilityMaven.h"
|
||||
#include "Application.h"
|
||||
|
||||
QtProjectWizzardContentPath::QtProjectWizzardContentPath(QtProjectWizzardWindow* window)
|
||||
: QtProjectWizzardContent(window)
|
||||
@@ -744,6 +746,20 @@ QtProjectWizzardContentPathPythonEnvironment::QtProjectWizzardContentPathPythonE
|
||||
setAllowEmpty(true);
|
||||
}
|
||||
|
||||
void QtProjectWizzardContentPathPythonEnvironment::populate(QGridLayout* layout, int& row)
|
||||
{
|
||||
QtProjectWizzardContentPath::populate(layout, row);
|
||||
connect(
|
||||
m_picker, &QtLocationPicker::textChanged,
|
||||
this, &QtProjectWizzardContentPathPythonEnvironment::onTextChanged
|
||||
);
|
||||
|
||||
m_resultLabel = new QLabel();
|
||||
m_resultLabel->setWordWrap(true);
|
||||
layout->addWidget(m_resultLabel, row, QtProjectWizzardWindow::BACK_COL);
|
||||
row++;
|
||||
}
|
||||
|
||||
void QtProjectWizzardContentPathPythonEnvironment::load()
|
||||
{
|
||||
m_picker->setText(QString::fromStdWString(m_settings->getEnvironmentDirectoryPath().wstr()));
|
||||
@@ -754,6 +770,39 @@ void QtProjectWizzardContentPathPythonEnvironment::save()
|
||||
m_settings->setEnvironmentDirectoryPath(FilePath(m_picker->getText().toStdWString()));
|
||||
}
|
||||
|
||||
void QtProjectWizzardContentPathPythonEnvironment::onTextChanged(const QString& text)
|
||||
{
|
||||
if (text.isEmpty())
|
||||
{
|
||||
m_resultLabel->clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_resultLabel->setText("Checking validity of Python environment...");
|
||||
std::thread([=]() {
|
||||
std::pair<int, std::string> out = utility::executeProcess(
|
||||
"\"" + ResourcePaths::getPythonPath().str() + "SourcetrailPythonIndexer\" check-environment " +
|
||||
"--environment-path \"" + m_settings->makePathExpandedAndAbsolute(FilePath(text.toStdWString())).str() + "\"",
|
||||
FilePath(),
|
||||
5000
|
||||
);
|
||||
m_onQtThread(
|
||||
[=]()
|
||||
{
|
||||
if (out.first == 0)
|
||||
{
|
||||
m_resultLabel->setText(QString::fromStdString(out.second));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_resultLabel->setText("An error occurred while checking environment path. Unable to check validity.");
|
||||
}
|
||||
}
|
||||
);
|
||||
}).detach();
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<SourceGroupSettings> QtProjectWizzardContentPathPythonEnvironment::getSourceGroupSettings()
|
||||
{
|
||||
return m_settings;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <set>
|
||||
|
||||
#include "QtProjectWizzardContent.h"
|
||||
#include "QtThreadedFunctor.h"
|
||||
#include "SingleValueCache.h"
|
||||
|
||||
class QCheckBox;
|
||||
@@ -245,13 +246,17 @@ public:
|
||||
QtProjectWizzardContentPathPythonEnvironment(std::shared_ptr<SourceGroupSettingsPythonEmpty> settings, QtProjectWizzardWindow* window);
|
||||
|
||||
// QtProjectWizzardContent implementation
|
||||
void populate(QGridLayout* layout, int& row) override;
|
||||
void load() override;
|
||||
void save() override;
|
||||
|
||||
private:
|
||||
void onTextChanged(const QString& text);
|
||||
std::shared_ptr<SourceGroupSettings> getSourceGroupSettings() override;
|
||||
|
||||
std::shared_ptr<SourceGroupSettingsPythonEmpty> m_settings;
|
||||
QtThreadedLambdaFunctor m_onQtThread;
|
||||
QLabel* m_resultLabel;
|
||||
};
|
||||
|
||||
#endif // QT_PROJECT_WIZZARD_CONTENT_PATH_H
|
||||
|
||||
@@ -26,7 +26,7 @@ void QtProjectWizzardContentSelect::populate(QGridLayout* layout, int& row)
|
||||
{
|
||||
std::string pythonIndexerVersion = " ";
|
||||
{
|
||||
std::string str = utility::executeProcess("\"" + ResourcePaths::getPythonPath().str() + "SourcetrailPythonIndexer\" --version", FilePath(), 5000);
|
||||
std::string str = utility::executeProcess("\"" + ResourcePaths::getPythonPath().str() + "SourcetrailPythonIndexer\" --version", FilePath(), 5000).second;
|
||||
std::regex regex("v\\d*\\.db\\d*\\.p\\d*"); // "\\d" matches any digit; "\\." matches the "." character
|
||||
std::smatch matches;
|
||||
std::regex_search(str, matches, regex);
|
||||
|
||||
@@ -23,7 +23,7 @@ std::vector<FilePath> CxxVs15HeaderPathDetector::getPaths() const
|
||||
{
|
||||
const std::string command = "\"" + expandedPaths[0].str() + "\" -latest -property installationPath";
|
||||
const std::string command2 = "\"C:/Program Files (x86)/Microsoft Visual Studio/Installer/vswhere.exe\"";
|
||||
const std::string output = utility::executeProcess(command, FilePath(), 10000);
|
||||
const std::string output = utility::executeProcess(command, FilePath(), 10000).second;
|
||||
|
||||
const FilePath vsInstallPath(output);
|
||||
if (vsInstallPath.exists())
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace utility
|
||||
std::vector<std::string> getCxxHeaderPaths(const std::string& compilerName)
|
||||
{
|
||||
std::string command = compilerName + " -x c++ -v -E /dev/null";
|
||||
std::string clangOutput = utility::executeProcess(command.c_str());
|
||||
std::string clangOutput = utility::executeProcess(command.c_str()).second;
|
||||
std::string standardHeaders =
|
||||
utility::substrBetween<std::string>(clangOutput, "#include <...> search starts here:\n","\nEnd of search list");
|
||||
std::vector<std::string> paths;
|
||||
|
||||
@@ -19,7 +19,7 @@ JavaPathDetectorLinux::JavaPathDetectorLinux(const std::string javaVersion)
|
||||
FilePath JavaPathDetectorLinux::getJavaInPath() const
|
||||
{
|
||||
std::string command = "which java";
|
||||
std::string output = utility::executeProcess(command.c_str());
|
||||
std::string output = utility::executeProcess(command.c_str()).second;
|
||||
|
||||
if (!output.empty())
|
||||
{
|
||||
@@ -38,7 +38,7 @@ FilePath JavaPathDetectorLinux::getJavaInPath() const
|
||||
FilePath JavaPathDetectorLinux::readLink(const FilePath& path) const
|
||||
{
|
||||
std::string command = "readlink -f " + path.str();
|
||||
FilePath javaPath( utility::executeProcess(command.c_str()));
|
||||
FilePath javaPath( utility::executeProcess(command.c_str()).second);
|
||||
if (!javaPath.empty())
|
||||
{
|
||||
return javaPath;
|
||||
@@ -77,7 +77,7 @@ FilePath JavaPathDetectorLinux::getJavaInJavaHome() const
|
||||
bool JavaPathDetectorLinux::checkVersion(const FilePath& path) const
|
||||
{
|
||||
std::string command = path.str() + " -version";
|
||||
std::string output = utility::executeProcess(command.c_str());
|
||||
std::string output = utility::executeProcess(command.c_str()).second;
|
||||
|
||||
return output.find(m_javaVersion) != std::string::npos;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ std::vector<FilePath> JavaPathDetectorMac::getPaths() const
|
||||
FilePath javaPath;
|
||||
|
||||
std::string command = "/usr/libexec/java_home";
|
||||
std::string output = utility::executeProcess(command.c_str());
|
||||
std::string output = utility::executeProcess(command.c_str()).second;
|
||||
|
||||
if (!output.empty())
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ MavenPathDetectorUnix::MavenPathDetectorUnix()
|
||||
std::vector<FilePath> MavenPathDetectorUnix::getPaths() const
|
||||
{
|
||||
std::string command = "which mvn";
|
||||
FilePath mavenPath(utility::executeProcess(command.c_str()));
|
||||
FilePath mavenPath(utility::executeProcess(command.c_str()).second);
|
||||
|
||||
std::vector<FilePath> paths;
|
||||
if (mavenPath.exists())
|
||||
|
||||
@@ -11,7 +11,7 @@ MavenPathDetectorWindows::MavenPathDetectorWindows()
|
||||
std::vector<FilePath> MavenPathDetectorWindows::getPaths() const
|
||||
{
|
||||
std::string command = "cmd /c where mvn.cmd && exit";
|
||||
FilePath mavenPath(utility::executeProcess(command.c_str()));
|
||||
FilePath mavenPath(utility::executeProcess(command.c_str()).second);
|
||||
|
||||
std::vector<FilePath> paths;
|
||||
if (mavenPath.exists())
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace utility
|
||||
std::set<QProcess*> s_runningProcesses;
|
||||
}
|
||||
|
||||
std::string utility::executeProcess(const std::string& command, const FilePath& workingDirectory, const int timeout)
|
||||
std::pair<int, std::string> utility::executeProcess(const std::string& command, const FilePath& workingDirectory, const int timeout)
|
||||
{
|
||||
QProcess process;
|
||||
process.setProcessChannelMode(QProcess::MergedChannels);
|
||||
@@ -81,11 +81,11 @@ std::string utility::executeProcess(const std::string& command, const FilePath&
|
||||
|
||||
// QProcess::ProcessError error = process.error();
|
||||
|
||||
std::string processoutput = process.readAll().toStdString();
|
||||
const std::string processoutput = process.readAll().toStdString();
|
||||
const int exitCode = process.exitCode();
|
||||
process.close();
|
||||
processoutput = utility::trim(processoutput);
|
||||
|
||||
return processoutput;
|
||||
return std::make_pair(exitCode, utility::trim(processoutput));
|
||||
}
|
||||
|
||||
std::string utility::executeProcessUntilNoOutput(const std::string& command, const FilePath& workingDirectory, const int waitTime)
|
||||
|
||||
@@ -12,7 +12,7 @@ class License;
|
||||
|
||||
namespace utility
|
||||
{
|
||||
std::string executeProcess(const std::string& command, const FilePath& workingDirectory = FilePath(), const int timeout = 30000);
|
||||
std::pair<int, std::string> executeProcess(const std::string& command, const FilePath& workingDirectory = FilePath(), const int timeout = 30000);
|
||||
std::string executeProcessUntilNoOutput(const std::string& command, const FilePath& workingDirectory, int waitTime = 10000);
|
||||
int executeProcessAndGetExitCode(
|
||||
const std::wstring& commandPath,
|
||||
|
||||
@@ -49,7 +49,7 @@ std::vector<std::shared_ptr<IndexerCommand>> SourceGroupPythonEmpty::getIndexerC
|
||||
|
||||
if (!m_settings->getEnvironmentDirectoryPath().empty())
|
||||
{
|
||||
args += L" --environment-directory-path=" + m_settings->getEnvironmentDirectoryPathExpandedAndAbsolute().wstr();
|
||||
args += L" --environment-path=" + m_settings->getEnvironmentDirectoryPathExpandedAndAbsolute().wstr();
|
||||
}
|
||||
|
||||
if (ApplicationSettings::getInstance()->getVerboseIndexerLoggingEnabled())
|
||||
@@ -64,7 +64,7 @@ std::vector<std::shared_ptr<IndexerCommand>> SourceGroupPythonEmpty::getIndexerC
|
||||
{
|
||||
indexerCommands.push_back(std::make_shared<IndexerCommandCustom>(
|
||||
INDEXER_COMMAND_PYTHON,
|
||||
L"\"" + ResourcePaths::getPythonPath().wstr() + L"SourcetrailPythonIndexer\"" + args,
|
||||
L"\"" + ResourcePaths::getPythonPath().wstr() + L"SourcetrailPythonIndexer\" index" + args,
|
||||
m_settings->getProjectSettings()->getProjectFilePath(),
|
||||
m_settings->getProjectSettings()->getTempDBFilePath(),
|
||||
std::to_wstring(SqliteIndexStorage::getStorageVersion()),
|
||||
|
||||
Reference in New Issue
Block a user