split command line args for IndexerCommandCustom usages

* this seems to be required when using the new QProcess API.
* this also required to remove quotes that were added to path args because otherwise the Python indexer would mistake absolute paths for relative paths.
This commit is contained in:
mlangkabel
2021-01-25 20:36:42 +01:00
parent 093261232c
commit ecfa1b7920
17 changed files with 203 additions and 76 deletions
+37 -16
View File
@@ -11,7 +11,8 @@ IndexerCommandType IndexerCommandCustom::getStaticIndexerCommandType()
}
IndexerCommandCustom::IndexerCommandCustom(
const std::wstring& customCommand,
const std::wstring& command,
const std::vector<std::wstring>& arguments,
const FilePath& projectFilePath,
const FilePath& databaseFilePath,
const std::wstring& databaseVersion,
@@ -19,7 +20,8 @@ IndexerCommandCustom::IndexerCommandCustom(
bool runInParallel)
: IndexerCommand(sourceFilePath)
, m_type(getStaticIndexerCommandType())
, m_customCommand(customCommand)
, m_command(command)
, m_arguments(arguments)
, m_projectFilePath(projectFilePath)
, m_databaseFilePath(databaseFilePath)
, m_databaseVersion(databaseVersion)
@@ -29,7 +31,8 @@ IndexerCommandCustom::IndexerCommandCustom(
IndexerCommandCustom::IndexerCommandCustom(
IndexerCommandType type,
const std::wstring& customCommand,
const std::wstring& command,
const std::vector<std::wstring>& arguments,
const FilePath& projectFilePath,
const FilePath& databaseFilePath,
const std::wstring& databaseVersion,
@@ -37,7 +40,8 @@ IndexerCommandCustom::IndexerCommandCustom(
bool runInParallel)
: IndexerCommand(sourceFilePath)
, m_type(type)
, m_customCommand(customCommand)
, m_command(command)
, m_arguments(arguments)
, m_projectFilePath(projectFilePath)
, m_databaseFilePath(databaseFilePath)
, m_databaseVersion(databaseVersion)
@@ -67,19 +71,19 @@ void IndexerCommandCustom::setDatabaseFilePath(const FilePath& databaseFilePath)
m_databaseFilePath = databaseFilePath;
}
std::wstring IndexerCommandCustom::getCustomCommand() const
std::wstring IndexerCommandCustom::getCommand() const
{
std::wstring command = m_customCommand;
return replaceVariables(m_command);
}
command = utility::replace(
command, L"%{PROJECT_FILE_PATH}", L'\"' + m_projectFilePath.wstr() + L'\"');
command = utility::replace(
command, L"%{DATABASE_FILE_PATH}", L'\"' + m_databaseFilePath.wstr() + L'\"');
command = utility::replace(command, L"%{DATABASE_VERSION}", L'\"' + m_databaseVersion + L'\"');
command = utility::replace(
command, L"%{SOURCE_FILE_PATH}", L'\"' + getSourceFilePath().wstr() + L'\"');
return command;
std::vector<std::wstring> IndexerCommandCustom::getArguments() const
{
std::vector<std::wstring> args;
for (const std::wstring& argument: m_arguments)
{
args.push_back(replaceVariables(argument));
}
return args;
}
bool IndexerCommandCustom::getRunInParallel() const
@@ -92,7 +96,15 @@ QJsonObject IndexerCommandCustom::doSerialize() const
QJsonObject jsonObject = IndexerCommand::doSerialize();
{
jsonObject["custom_command"] = QString::fromStdWString(m_customCommand);
jsonObject["command"] = QString::fromStdWString(m_command);
}
{
QJsonArray argumentsArray;
for (const std::wstring& argument: m_arguments)
{
argumentsArray.append(QString::fromStdWString(argument));
}
jsonObject["arguments"] = argumentsArray;
}
{
jsonObject["run_in_parallel"] = m_runInParallel;
@@ -100,3 +112,12 @@ QJsonObject IndexerCommandCustom::doSerialize() const
return jsonObject;
}
std::wstring IndexerCommandCustom::replaceVariables(std::wstring s) const
{
s = utility::replace(s, L"%{PROJECT_FILE_PATH}", m_projectFilePath.wstr());
s = utility::replace(s, L"%{DATABASE_FILE_PATH}", m_databaseFilePath.wstr());
s = utility::replace(s, L"%{DATABASE_VERSION}", m_databaseVersion);
s = utility::replace(s, L"%{SOURCE_FILE_PATH}", getSourceFilePath().wstr());
return s;
}
+10 -4
View File
@@ -12,7 +12,8 @@ public:
static IndexerCommandType getStaticIndexerCommandType();
IndexerCommandCustom(
const std::wstring& customCommand,
const std::wstring& command,
const std::vector<std::wstring>& arguments,
const FilePath& projectFilePath,
const FilePath& databaseFilePath,
const std::wstring& databaseVersion,
@@ -21,7 +22,8 @@ public:
IndexerCommandCustom(
IndexerCommandType type,
const std::wstring& customCommand,
const std::wstring& command,
const std::vector<std::wstring>& arguments,
const FilePath& projectFilePath,
const FilePath& databaseFilePath,
const std::wstring& databaseVersion,
@@ -34,15 +36,19 @@ public:
FilePath getDatabaseFilePath() const;
void setDatabaseFilePath(const FilePath& databaseFilePath);
std::wstring getCustomCommand() const;
std::wstring getCommand() const;
std::vector<std::wstring> getArguments() const;
bool getRunInParallel() const;
protected:
QJsonObject doSerialize() const override;
private:
std::wstring replaceVariables(std::wstring s) const;
IndexerCommandType m_type;
std::wstring m_customCommand;
std::wstring m_command;
std::vector<std::wstring> m_arguments;
FilePath m_projectFilePath;
FilePath m_databaseFilePath;
std::wstring m_databaseVersion;
@@ -465,9 +465,12 @@ void TaskExecuteCustomCommands::runIndexerCommand(
indexedSourceFileCount + 1, indexedSourceFileCount, m_indexerCommandCount, {sourcePath});
MessageIndexingStatus(true, indexedSourceFileCount * 100 / m_indexerCommandCount).dispatch();
const std::wstring command = indexerCommand->getCustomCommand();
const std::wstring command = indexerCommand->getCommand();
const std::vector<std::wstring> arguments = indexerCommand->getArguments();
LOG_INFO("Start processing command \"" + utility::encodeToUtf8(command) + "\"");
LOG_INFO(
"Start processing command \"" +
utility::encodeToUtf8(command + L" " + utility::join(arguments, L" ")) + "\"");
const ErrorCountInfo previousErrorCount = storage ? storage->getErrorCount()
: ErrorCountInfo();
@@ -475,7 +478,7 @@ void TaskExecuteCustomCommands::runIndexerCommand(
LOG_INFO("Starting to index");
std::wstring errorMessage;
const int result = utility::executeProcessAndGetExitCode(
command, {}, m_projectDirectory, -1, true, &errorMessage);
command, arguments, m_projectDirectory, -1, true, &errorMessage);
LOG_INFO("Finished indexing");
if (storage)
@@ -508,8 +511,9 @@ void TaskExecuteCustomCommands::runIndexerCommand(
}
else
{
std::wstring statusText = L"command \"" + indexerCommand->getCustomCommand() +
L"\" returned";
std::wstring statusText = L"command \"" + indexerCommand->getCommand() + L" " +
utility::join(arguments, L" ") + L"\" returned";
if (result != 0)
{
statusText += L" code \"" + std::to_wstring(result) + L"\"";
+63 -2
View File
@@ -42,7 +42,67 @@ std::set<FilePath> SourceGroupCustomCommand::getAllSourceFilePaths() const
std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCustomCommand::getIndexerCommands(
const RefreshInfo& info) const
{
const std::wstring customCommand = m_settings->getCustomCommand();
std::vector<std::wstring> parts;
{
const std::wstring customCommand = m_settings->getCustomCommand();
std::wstring tmp;
int quoteCount = 0;
bool inQuote = false;
// handle quoting. tokens can be surrounded by double quotes
// "hello world". three consecutive double quotes represent
// the quote character itself.
for (int i = 0; i < customCommand.size(); ++i)
{
if (customCommand.at(i) == L'"')
{
++quoteCount;
if (quoteCount == 3) // third consecutive quote
{
quoteCount = 0;
tmp += customCommand.at(i);
}
continue;
}
if (quoteCount)
{
if (quoteCount == 1)
{
inQuote = !inQuote;
}
quoteCount = 0;
}
if (!inQuote && customCommand.at(i) == L' ')
{
if (!tmp.empty())
{
parts.push_back(tmp);
tmp.clear();
}
}
else
{
tmp += customCommand.at(i);
}
}
if (!tmp.empty())
{
parts.push_back(tmp);
}
}
if (parts.empty())
{
return {};
}
const std::wstring command = parts.front();
std::vector<std::wstring> args;
for (size_t i = 1; i < parts.size(); i++)
{
args.push_back(parts[i]);
}
const bool runInParallel = m_settings->getRunInParallel();
std::vector<std::shared_ptr<IndexerCommand>> indexerCommands;
@@ -51,7 +111,8 @@ std::vector<std::shared_ptr<IndexerCommand>> SourceGroupCustomCommand::getIndexe
if (info.filesToIndex.find(sourcePath) != info.filesToIndex.end())
{
indexerCommands.push_back(std::make_shared<IndexerCommandCustom>(
customCommand,
command,
args,
m_settings->getProjectSettings()->getProjectFilePath(),
m_settings->getProjectSettings()->getTempDBFilePath(),
std::to_wstring(SqliteIndexStorage::getStorageVersion()),