diff --git a/bin/app/data/gui/window/window.css b/bin/app/data/gui/window/window.css index 62aa65d3..af32cf41 100644 --- a/bin/app/data/gui/window/window.css +++ b/bin/app/data/gui/window/window.css @@ -134,7 +134,8 @@ QCheckBox:disabled { #menuButton { background: white; - border: none; + border: 2px solid #CFD2E0; + border-right: none; border-radius: 8px; border-bottom-right-radius: 0px; border-top-right-radius: 0px; diff --git a/bin/test/data/SourceGroupTestSuite/custom_command/expected_output/output.txt b/bin/test/data/SourceGroupTestSuite/custom_command/expected_output/output.txt new file mode 100644 index 00000000..552d7d1e --- /dev/null +++ b/bin/test/data/SourceGroupTestSuite/custom_command/expected_output/output.txt @@ -0,0 +1,6 @@ +SourceFilePath: "src/a.txt" + Custom Command: "echo "Hello World"" +SourceFilePath: "src/b.txt" + Custom Command: "echo "Hello World"" +SourceFilePath: "src/included/a.txt" + Custom Command: "echo "Hello World"" diff --git a/bin/test/data/SourceGroupTestSuite/custom_command/input/src/a.txt b/bin/test/data/SourceGroupTestSuite/custom_command/input/src/a.txt new file mode 100644 index 00000000..9c558e35 --- /dev/null +++ b/bin/test/data/SourceGroupTestSuite/custom_command/input/src/a.txt @@ -0,0 +1 @@ +. diff --git a/bin/test/data/SourceGroupTestSuite/custom_command/input/src/b.txt b/bin/test/data/SourceGroupTestSuite/custom_command/input/src/b.txt new file mode 100644 index 00000000..9c558e35 --- /dev/null +++ b/bin/test/data/SourceGroupTestSuite/custom_command/input/src/b.txt @@ -0,0 +1 @@ +. diff --git a/bin/test/data/SourceGroupTestSuite/custom_command/input/src/excluded/b.txt b/bin/test/data/SourceGroupTestSuite/custom_command/input/src/excluded/b.txt new file mode 100644 index 00000000..9c558e35 --- /dev/null +++ b/bin/test/data/SourceGroupTestSuite/custom_command/input/src/excluded/b.txt @@ -0,0 +1 @@ +. diff --git a/bin/test/data/SourceGroupTestSuite/custom_command/input/src/included/a.txt b/bin/test/data/SourceGroupTestSuite/custom_command/input/src/included/a.txt new file mode 100644 index 00000000..9c558e35 --- /dev/null +++ b/bin/test/data/SourceGroupTestSuite/custom_command/input/src/included/a.txt @@ -0,0 +1 @@ +. diff --git a/src/app/main.cpp b/src/app/main.cpp index 7fc4571c..d458ff01 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -9,6 +9,7 @@ #include "SourceGroupFactory.h" #include "SourceGroupFactoryModuleCxx.h" #include "SourceGroupFactoryModuleJava.h" +#include "SourceGroupFactoryModuleCustom.h" #include "QtNetworkFactory.h" #include "QtApplication.h" #include "QtCoreApplication.h" @@ -184,6 +185,7 @@ void addLanguagePackages() { SourceGroupFactory::getInstance()->addModule(std::make_shared()); SourceGroupFactory::getInstance()->addModule(std::make_shared()); + SourceGroupFactory::getInstance()->addModule(std::make_shared()); LanguagePackageManager::getInstance()->addPackage(std::make_shared()); LanguagePackageManager::getInstance()->addPackage(std::make_shared()); diff --git a/src/indexer/main.cpp b/src/indexer/main.cpp index b4823ad0..db5bfce0 100644 --- a/src/indexer/main.cpp +++ b/src/indexer/main.cpp @@ -15,10 +15,10 @@ void setupLogging(const FilePath& logFilePath) { LogManager* logManager = LogManager::getInstance().get(); - std::shared_ptr consoleLogger = std::make_shared(); - // consoleLogger->setLogLevel(Logger::LOG_WARNINGS | Logger::LOG_ERRORS); - consoleLogger->setLogLevel(Logger::LOG_ALL); - logManager->addLogger(consoleLogger); + // std::shared_ptr consoleLogger = std::make_shared(); + // // consoleLogger->setLogLevel(Logger::LOG_WARNINGS | Logger::LOG_ERRORS); + // consoleLogger->setLogLevel(Logger::LOG_ALL); + // logManager->addLogger(consoleLogger); std::shared_ptr fileLogger = std::make_shared(); fileLogger->setLogFilePath(logFilePath); diff --git a/src/lib/Application.cpp b/src/lib/Application.cpp index 5ab30bc0..e889e597 100644 --- a/src/lib/Application.cpp +++ b/src/lib/Application.cpp @@ -378,7 +378,7 @@ FilePath Application::migrateProjectSettings(const FilePath& projectSettingsFile if (projectSettingsFilePath.extension() == L".coatiproject") { MessageStatus(L"Migrating deprecated project file extension \".coatiproject\" to new file extension \".srctrlprj\"").dispatch(); - const FilePath newSettingsPath = projectSettingsFilePath.replaceExtension(Project::PROJECT_FILE_EXTENSION); + const FilePath newSettingsPath = projectSettingsFilePath.replaceExtension(ProjectSettings::PROJECT_FILE_EXTENSION); { FileSystem::rename(projectSettingsFilePath, newSettingsPath); const FilePath oldDbPath = projectSettingsFilePath.replaceExtension(L"coatidb"); diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index fe5473f4..228fa371 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -174,6 +174,8 @@ add_files( data/indexer/IndexerBase.h data/indexer/IndexerCommand.cpp data/indexer/IndexerCommand.h + data/indexer/IndexerCommandCustom.cpp + data/indexer/IndexerCommandCustom.h data/indexer/IndexerCommandProvider.cpp data/indexer/IndexerCommandProvider.h data/indexer/IndexerCommandType.cpp @@ -185,6 +187,8 @@ add_files( data/indexer/MemoryIndexerCommandProvider.h data/indexer/TaskBuildIndex.cpp data/indexer/TaskBuildIndex.h + data/indexer/TaskExecuteCustomCommands.cpp + data/indexer/TaskExecuteCustomCommands.h data/indexer/TaskFillIndexerCommandQueue.cpp data/indexer/TaskFillIndexerCommandQueue.h @@ -298,10 +302,14 @@ add_files( project/RefreshInfoGenerator.cpp project/SourceGroup.cpp project/SourceGroup.h + project/SourceGroupCustomCommand.cpp + project/SourceGroupCustomCommand.h project/SourceGroupFactory.cpp project/SourceGroupFactory.h project/SourceGroupFactoryModule.cpp project/SourceGroupFactoryModule.h + project/SourceGroupFactoryModuleCustom.cpp + project/SourceGroupFactoryModuleCustom.h settings/migration/SettingsMigration.cpp settings/migration/SettingsMigration.h @@ -325,12 +333,15 @@ add_files( settings/Settings.h settings/SourceGroupSettings.cpp settings/SourceGroupSettings.h + settings/SourceGroupSettingsBase.h settings/SourceGroupSettingsCxx.cpp settings/SourceGroupSettingsCxx.h settings/SourceGroupSettingsCEmpty.cpp settings/SourceGroupSettingsCEmpty.h settings/SourceGroupSettingsCppEmpty.cpp settings/SourceGroupSettingsCppEmpty.h + settings/SourceGroupSettingsCustomCommand.cpp + settings/SourceGroupSettingsCustomCommand.h settings/SourceGroupSettingsCxxCdb.cpp settings/SourceGroupSettingsCxxCdb.h settings/SourceGroupSettingsCxxCdbVs.cpp diff --git a/src/lib/component/view/DialogView.cpp b/src/lib/component/view/DialogView.cpp index ea718f3f..c30a6465 100644 --- a/src/lib/component/view/DialogView.cpp +++ b/src/lib/component/view/DialogView.cpp @@ -52,6 +52,11 @@ void DialogView::updateIndexingDialog( { } +void DialogView::updateCustomIndexingDialog( + size_t startedFileCount, size_t finishedFileCount, size_t totalFileCount, const std::vector& sourcePaths) +{ +} + DatabasePolicy DialogView::finishedIndexingDialog( size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo, bool interrupted) diff --git a/src/lib/component/view/DialogView.h b/src/lib/component/view/DialogView.h index 2cd500c2..6d575bef 100644 --- a/src/lib/component/view/DialogView.h +++ b/src/lib/component/view/DialogView.h @@ -49,6 +49,8 @@ public: std::function onStartIndexing, std::function onCancelIndexing); virtual void updateIndexingDialog( size_t startedFileCount, size_t finishedFileCount, size_t totalFileCount, const std::vector& sourcePaths); + virtual void updateCustomIndexingDialog( + size_t startedFileCount, size_t finishedFileCount, size_t totalFileCount, const std::vector& sourcePaths); virtual DatabasePolicy finishedIndexingDialog( size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo, bool interrupted); diff --git a/src/lib/data/indexer/IndexerCommandCustom.cpp b/src/lib/data/indexer/IndexerCommandCustom.cpp new file mode 100644 index 00000000..83398185 --- /dev/null +++ b/src/lib/data/indexer/IndexerCommandCustom.cpp @@ -0,0 +1,46 @@ +#include "IndexerCommandCustom.h" + +#include +#include + +IndexerCommandType IndexerCommandCustom::getStaticIndexerCommandType() +{ + return INDEXER_COMMAND_CUSTOM; +} + +IndexerCommandCustom::IndexerCommandCustom( + const FilePath& sourceFilePath, + const std::wstring& customCommand +) + : IndexerCommand(sourceFilePath) + , m_customCommand(customCommand) +{ +} + +IndexerCommandType IndexerCommandCustom::getIndexerCommandType() const +{ + return getStaticIndexerCommandType(); +} + +size_t IndexerCommandCustom::getByteSize(size_t stringSize) const +{ + size_t size = IndexerCommand::getByteSize(stringSize); + + return size; +} + +const std::wstring& IndexerCommandCustom::getCustomCommand() const +{ + return m_customCommand; +} + +QJsonObject IndexerCommandCustom::doSerialize() const +{ + QJsonObject jsonObject = IndexerCommand::doSerialize(); + + { + jsonObject["custom_command"] = QString::fromStdWString(m_customCommand); + } + + return jsonObject; +} diff --git a/src/lib/data/indexer/IndexerCommandCustom.h b/src/lib/data/indexer/IndexerCommandCustom.h new file mode 100644 index 00000000..f7dfd6bc --- /dev/null +++ b/src/lib/data/indexer/IndexerCommandCustom.h @@ -0,0 +1,29 @@ +#ifndef INDEXER_COMMAND_CUSTOM_H +#define INDEXER_COMMAND_CUSTOM_H + +#include +#include + +#include "IndexerCommand.h" + +class IndexerCommandCustom + : public IndexerCommand +{ +public: + static IndexerCommandType getStaticIndexerCommandType(); + + IndexerCommandCustom(const FilePath& sourceFilePath, const std::wstring& customCommand); + + IndexerCommandType getIndexerCommandType() const override; + size_t getByteSize(size_t stringSize) const override; + + const std::wstring& getCustomCommand() const; + +protected: + QJsonObject doSerialize() const override; + +private: + std::wstring m_customCommand; +}; + +#endif // INDEXER_COMMAND_CXXL_H diff --git a/src/lib/data/indexer/IndexerCommandType.cpp b/src/lib/data/indexer/IndexerCommandType.cpp index 2851060d..0e48310e 100644 --- a/src/lib/data/indexer/IndexerCommandType.cpp +++ b/src/lib/data/indexer/IndexerCommandType.cpp @@ -8,6 +8,8 @@ std::string indexerCommandTypeToString(IndexerCommandType type) return "indexer_command_cxx"; case INDEXER_COMMAND_JAVA: return "indexer_command_java"; + case INDEXER_COMMAND_CUSTOM: + return "indexer_command_custom"; default: break; } @@ -18,6 +20,7 @@ IndexerCommandType stringToIndexerCommandType(const std::string& s) { if (s == indexerCommandTypeToString(INDEXER_COMMAND_CXX)) return INDEXER_COMMAND_CXX; if (s == indexerCommandTypeToString(INDEXER_COMMAND_JAVA)) return INDEXER_COMMAND_JAVA; + if (s == indexerCommandTypeToString(INDEXER_COMMAND_CUSTOM)) return INDEXER_COMMAND_CUSTOM; return INDEXER_COMMAND_UNKNOWN; } diff --git a/src/lib/data/indexer/IndexerCommandType.h b/src/lib/data/indexer/IndexerCommandType.h index 468fdce5..4541bd20 100644 --- a/src/lib/data/indexer/IndexerCommandType.h +++ b/src/lib/data/indexer/IndexerCommandType.h @@ -8,6 +8,7 @@ enum IndexerCommandType INDEXER_COMMAND_UNKNOWN, INDEXER_COMMAND_CXX, INDEXER_COMMAND_JAVA, + INDEXER_COMMAND_CUSTOM }; std::string indexerCommandTypeToString(IndexerCommandType type); diff --git a/src/lib/data/indexer/TaskExecuteCustomCommands.cpp b/src/lib/data/indexer/TaskExecuteCustomCommands.cpp new file mode 100644 index 00000000..4837612c --- /dev/null +++ b/src/lib/data/indexer/TaskExecuteCustomCommands.cpp @@ -0,0 +1,94 @@ +#include "TaskExecuteCustomCommands.h" + +#include "Blackboard.h" +#include "DialogView.h" +#include "IndexerCommandCustom.h" +#include "IndexerCommandProvider.h" +#include "MessageIndexingStatus.h" +#include "MessageShowStatus.h" +#include "MessageStatus.h" +#include "utility.h" +#include "utilityApp.h" +#include "utilityString.h" + +TaskExecuteCustomCommands::TaskExecuteCustomCommands( + std::unique_ptr indexerCommandProvider, std::shared_ptr dialogView, const FilePath& projectDirectory +) + : m_indexerCommandProvider(std::move(indexerCommandProvider)) + , m_dialogView(dialogView) + , m_projectDirectory(projectDirectory) +{ +} + +void TaskExecuteCustomCommands::doEnter(std::shared_ptr blackboard) +{ + m_dialogView->hideUnknownProgressDialog(); + m_start = utility::durationStart(); +} + +Task::TaskState TaskExecuteCustomCommands::doUpdate(std::shared_ptr blackboard) +{ + if (m_interrupted) + { + return STATE_SUCCESS; + } + + int sourceFileCount = m_indexerCommandProvider->size(); + int indexedSourceFileCount = 0; + m_dialogView->updateCustomIndexingDialog(0, 0, sourceFileCount, { }); + + while (!m_interrupted && m_indexerCommandProvider->size()) + { + std::shared_ptr indexerCommand = + std::dynamic_pointer_cast(m_indexerCommandProvider->consumeCommand()); + if (indexerCommand) + { + FilePath sourcePath = indexerCommand->getSourceFilePath(); + m_dialogView->updateCustomIndexingDialog(indexedSourceFileCount + 1, indexedSourceFileCount, sourceFileCount, { sourcePath }); + MessageIndexingStatus(true, indexedSourceFileCount * 100 / sourceFileCount).dispatch(); + LOG_INFO_STREAM(<< "Execute command \"" << utility::encodeToUtf8(indexerCommand->getCustomCommand()) << "\""); + + std::wstring processOutput; + int result = utility::executeProcessAndGetExitCode(indexerCommand->getCustomCommand(), {}, m_projectDirectory, -1, &processOutput); + + if (processOutput.size() > 3 || result != 0) + { + if (result == 0) + { + LOG_INFO_STREAM(<< "process return 0:\n" << utility::encodeToUtf8(processOutput)); + } + else + { + LOG_ERROR_STREAM(<< "process returned " << result << ":\n" << utility::encodeToUtf8(processOutput)); + MessageShowStatus().dispatch(); + MessageStatus(L"command <" + indexerCommand->getCustomCommand() + L"> returned " + + std::to_wstring(result) + L": " + processOutput, true, false, true).dispatch(); + } + } + + indexedSourceFileCount++; + blackboard->update("indexed_source_file_count", [=](int count) { return count + 1; }); + } + } + + return STATE_SUCCESS; +} + +void TaskExecuteCustomCommands::doExit(std::shared_ptr blackboard) +{ + float duration = utility::duration(m_start); + blackboard->update("index_time", [duration](float currentDuration) { return currentDuration + duration; }); +} + +void TaskExecuteCustomCommands::doReset(std::shared_ptr blackboard) +{ +} + +void TaskExecuteCustomCommands::handleMessage(MessageIndexingInterrupted* message) +{ + LOG_INFO("Interrupting custom command execution."); + + m_interrupted = true; + + m_dialogView->showUnknownProgressDialog(L"Interrupting Indexing", L"Waiting for running\ncommand to finish"); +} diff --git a/src/lib/data/indexer/TaskExecuteCustomCommands.h b/src/lib/data/indexer/TaskExecuteCustomCommands.h new file mode 100644 index 00000000..29afae38 --- /dev/null +++ b/src/lib/data/indexer/TaskExecuteCustomCommands.h @@ -0,0 +1,41 @@ +#ifndef TASK_EXECUTE_CUSTOM_COMMANDS_H +#define TASK_EXECUTE_CUSTOM_COMMANDS_H + +#include + +#include "FilePath.h" +#include "Task.h" +#include "TimeStamp.h" +#include "MessageIndexingInterrupted.h" +#include "MessageListener.h" + +class DialogView; +class IndexerCommandProvider; + +class TaskExecuteCustomCommands + : public Task + , public MessageListener +{ +public: + TaskExecuteCustomCommands( + std::unique_ptr indexerCommandProvider, + std::shared_ptr dialogView, + const FilePath& projectDirectory); + +private: + void doEnter(std::shared_ptr blackboard) override; + TaskState doUpdate(std::shared_ptr blackboard) override; + void doExit(std::shared_ptr blackboard) override; + void doReset(std::shared_ptr blackboard) override; + + void handleMessage(MessageIndexingInterrupted* message) override; + + std::unique_ptr m_indexerCommandProvider; + std::shared_ptr m_dialogView; + const FilePath m_projectDirectory; + + TimeStamp m_start; + bool m_interrupted = false; +}; + +#endif // TASK_EXECUTE_CUSTOM_COMMANDS_H diff --git a/src/lib/data/parser/TaskParseWrapper.cpp b/src/lib/data/parser/TaskParseWrapper.cpp index e8ec4dd7..20a3b9c0 100644 --- a/src/lib/data/parser/TaskParseWrapper.cpp +++ b/src/lib/data/parser/TaskParseWrapper.cpp @@ -37,7 +37,8 @@ Task::TaskState TaskParseWrapper::doUpdate(std::shared_ptr blackboar void TaskParseWrapper::doExit(std::shared_ptr blackboard) { - blackboard->set("index_time", utility::duration(m_start)); + float duration = utility::duration(m_start); + blackboard->update("index_time", [duration](float currentDuration) { return currentDuration + duration; }); } void TaskParseWrapper::doReset(std::shared_ptr blackboard) diff --git a/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp b/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp index 51b8a301..d7d57f93 100644 --- a/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp +++ b/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp @@ -44,6 +44,11 @@ namespace } } +size_t SqliteIndexStorage::getStorageVersion() +{ + return s_storageVersion; +} + SqliteIndexStorage::SqliteIndexStorage(const FilePath& dbFilePath) : SqliteStorage(dbFilePath.getCanonical()) { diff --git a/src/lib/data/storage/sqlite/SqliteIndexStorage.h b/src/lib/data/storage/sqlite/SqliteIndexStorage.h index e2278b5e..127013df 100644 --- a/src/lib/data/storage/sqlite/SqliteIndexStorage.h +++ b/src/lib/data/storage/sqlite/SqliteIndexStorage.h @@ -32,6 +32,8 @@ class SqliteIndexStorage : public SqliteStorage { public: + static size_t getStorageVersion(); + enum StorageModeType { STORAGE_MODE_READ = 1, diff --git a/src/lib/project/Project.cpp b/src/lib/project/Project.cpp index d26fef25..ecdfcfb8 100644 --- a/src/lib/project/Project.cpp +++ b/src/lib/project/Project.cpp @@ -3,7 +3,9 @@ #include "DialogView.h" #include "CombinedIndexerCommandProvider.h" #include "IndexerCommand.h" +#include "IndexerCommandCustom.h" #include "TaskBuildIndex.h" +#include "TaskExecuteCustomCommands.h" #include "TaskFillIndexerCommandQueue.h" #include "TaskParseWrapper.h" #include "PersistentStorage.h" @@ -43,11 +45,6 @@ #include "utilityFile.h" #include "utilityString.h" -const std::wstring Project::PROJECT_FILE_EXTENSION = L".srctrlprj"; -const std::wstring Project::BOOKMARK_DB_FILE_EXTENSION = L".srctrlbm"; -const std::wstring Project::INDEX_DB_FILE_EXTENSION = L".srctrldb"; -const std::wstring Project::TEMP_INDEX_DB_FILE_EXTENSION = L".srctrldb_tmp"; - Project::Project(std::shared_ptr settings, StorageCache* storageCache, const std::string& appUUID, bool hasGUI) : m_settings(settings) , m_storageCache(storageCache) @@ -124,10 +121,11 @@ void Project::load(std::shared_ptr dialogView) } const FilePath projectSettingsPath = m_settings->getFilePath(); + const FilePath dbPath = m_settings->getDBFilePath(); + const FilePath tempDbPath = m_settings->getTempDBFilePath(); + const FilePath bookmarkDbPath = m_settings->getBookmarkDBFilePath(); { - const FilePath dbPath = projectSettingsPath.replaceExtension(INDEX_DB_FILE_EXTENSION); - const FilePath tempDbPath = projectSettingsPath.replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION); if (tempDbPath.exists()) { if (dbPath.exists()) @@ -160,10 +158,7 @@ void Project::load(std::shared_ptr dialogView) } } - m_storage = std::make_shared( - projectSettingsPath.replaceExtension(INDEX_DB_FILE_EXTENSION), - projectSettingsPath.replaceExtension(BOOKMARK_DB_FILE_EXTENSION) - ); + m_storage = std::make_shared(dbPath, bookmarkDbPath); bool canLoad = false; @@ -399,7 +394,7 @@ RefreshInfo Project::getRefreshInfo(RefreshMode mode) const } } -void Project::buildIndex(const RefreshInfo& info, std::shared_ptr dialogView) +void Project::buildIndex(RefreshInfo info, std::shared_ptr dialogView) { if (m_refreshStage == RefreshStageType::INDEXING) { @@ -423,6 +418,45 @@ void Project::buildIndex(const RefreshInfo& info, std::shared_ptr di return; } + if (info.mode != REFRESH_ALL_FILES && (info.filesToClear.size() || info.nonIndexedFilesToClear.size())) + { + for (const std::shared_ptr& sourceGroup : m_sourceGroups) + { + if (sourceGroup->getStatus() == SOURCE_GROUP_STATUS_ENABLED && !sourceGroup->allowsPartialClearing()) + { + bool abortIndexing = false; + for (const FilePath& sourcePath : utility::concat(info.filesToClear, info.nonIndexedFilesToClear)) + { + if (sourceGroup->containsSourceFilePath(sourcePath)) + { + abortIndexing = true; + break; + } + } + + if (abortIndexing) + { + if (dialogView->confirm( + "

This project contains a source group of type \"" + sourceGroupTypeToString(sourceGroup->getType()) + "\" " + "that cannot be partially cleared. Do you want to re-index the whole project instead?

", + { "Full Re-Index", "Cancel" } + ) == 1) + { + MessageStatus(L"Cannot partially clear project. Indexing aborted.").dispatch(); + m_refreshStage = RefreshStageType::NONE; + return; + } + else + { + info = getRefreshInfo(REFRESH_ALL_FILES); + } + } + + break; + } + } + } + MessageStatus(L"Preparing Indexing", false, true).dispatch(); MessageErrorCountClear().dispatch(); @@ -432,8 +466,8 @@ void Project::buildIndex(const RefreshInfo& info, std::shared_ptr di m_storageCache->clear(); m_storageCache->setSubject(m_storage); - const FilePath indexDbFilePath = m_storage->getIndexDbFilePath(); - const FilePath tempIndexDbFilePath = indexDbFilePath.replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION); + const FilePath indexDbFilePath = m_settings->getDBFilePath(); + const FilePath tempIndexDbFilePath = m_settings->getTempDBFilePath(); if (info.mode != REFRESH_ALL_FILES) { @@ -460,15 +494,29 @@ void Project::buildIndex(const RefreshInfo& info, std::shared_ptr di tempStorage->updateVersion(); std::unique_ptr indexerCommandProvider = std::make_unique(); + std::unique_ptr customIndexerCommandProvider = std::make_unique(); for (const std::shared_ptr& sourceGroup : m_sourceGroups) { if (sourceGroup->getStatus() == SOURCE_GROUP_STATUS_ENABLED) { - indexerCommandProvider->addProvider(sourceGroup->getIndexerCommandProvider(info.filesToIndex)); + if (sourceGroup->getType() == SOURCE_GROUP_CUSTOM_COMMAND) + { + customIndexerCommandProvider->addProvider(sourceGroup->getIndexerCommandProvider(info.filesToIndex)); + } + else + { + indexerCommandProvider->addProvider(sourceGroup->getIndexerCommandProvider(info.filesToIndex)); + } } } - if (!info.filesToIndex.empty()) + taskSequential->addTask(std::make_shared>( + "source_file_count", indexerCommandProvider->size() + customIndexerCommandProvider->size())); + taskSequential->addTask(std::make_shared>("indexed_source_file_count", 0)); + taskSequential->addTask(std::make_shared>("interrupted_indexing", false)); + taskSequential->addTask(std::make_shared>("index_time", 0.0f)); + + if (indexerCommandProvider->size()) { int indexerThreadCount = ApplicationSettings::getInstance()->getIndexerThreadCount(); if (indexerThreadCount <= 0) @@ -480,12 +528,10 @@ void Project::buildIndex(const RefreshInfo& info, std::shared_ptr di } } - indexerThreadCount = std::min(indexerThreadCount, info.filesToIndex.size()); + indexerThreadCount = std::min(indexerThreadCount, indexerCommandProvider->size()); std::shared_ptr storageProvider = std::make_shared(); // add tasks for setting some variables on the blackboard that are used during indexing - taskSequential->addTask(std::make_shared>("source_file_count", indexerCommandProvider->size())); - taskSequential->addTask(std::make_shared>("indexed_source_file_count", 0)); taskSequential->addTask(std::make_shared>("indexer_threads_started", false)); taskSequential->addTask(std::make_shared>("indexer_threads_stopped", false)); taskSequential->addTask(std::make_shared>("indexer_command_queue_started", false)); @@ -567,6 +613,14 @@ void Project::buildIndex(const RefreshInfo& info, std::shared_ptr di dialogView->hideUnknownProgressDialog(); } + if (customIndexerCommandProvider->size()) + { + taskSequential->addTask( + std::make_shared( + std::move(customIndexerCommandProvider), dialogView, getProjectSettingsFilePath().getParentDirectory()) + ); + } + taskSequential->addTask(std::make_shared(tempStorage, dialogView)); taskSequential->addTask(std::make_shared()->addChildTasks( @@ -604,9 +658,9 @@ void Project::swapToTempStorage(std::shared_ptr dialogView) { LOG_INFO("Switching to temporary indexing data"); - const FilePath indexDbFilePath = m_storage->getIndexDbFilePath(); - const FilePath tempIndexDbFilePath = indexDbFilePath.replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION); - const FilePath bookmarkDbFilePath = m_storage->getBookmarkDbFilePath(); + const FilePath indexDbFilePath = m_settings->getDBFilePath(); + const FilePath tempIndexDbFilePath = m_settings->getTempDBFilePath(); + const FilePath bookmarkDbFilePath = m_settings->getBookmarkDBFilePath(); m_storage.reset(); @@ -652,7 +706,7 @@ bool Project::swapToTempStorageFile(const FilePath& indexDbFilePath, const FileP void Project::discardTempStorage() { - const FilePath tempIndexDbPath = m_storage->getIndexDbFilePath().replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION); + const FilePath tempIndexDbPath = m_settings->getTempDBFilePath(); if (tempIndexDbPath.exists()) { LOG_INFO("Discarding temporary indexing data"); diff --git a/src/lib/project/Project.h b/src/lib/project/Project.h index 4b99dffe..04b5e82f 100644 --- a/src/lib/project/Project.h +++ b/src/lib/project/Project.h @@ -19,11 +19,6 @@ class StorageCache; class Project { public: - static const std::wstring PROJECT_FILE_EXTENSION; - static const std::wstring BOOKMARK_DB_FILE_EXTENSION; - static const std::wstring INDEX_DB_FILE_EXTENSION; - static const std::wstring TEMP_INDEX_DB_FILE_EXTENSION; - Project(std::shared_ptr settings, StorageCache* storageCache, const std::string& appUUID, bool hasGUI); virtual ~Project(); @@ -42,7 +37,7 @@ public: RefreshInfo getRefreshInfo(RefreshMode mode) const; - void buildIndex(const RefreshInfo& info, std::shared_ptr dialogView); + void buildIndex(RefreshInfo info, std::shared_ptr dialogView); private: enum ProjectStateType diff --git a/src/lib/project/SourceGroup.cpp b/src/lib/project/SourceGroup.cpp index 60ac08f1..d0b3e419 100644 --- a/src/lib/project/SourceGroup.cpp +++ b/src/lib/project/SourceGroup.cpp @@ -3,6 +3,7 @@ #include "MemoryIndexerCommandProvider.h" #include "SourceGroupSettings.h" #include "FilePath.h" +#include "FilePathFilter.h" std::shared_ptr SourceGroup::getIndexerCommandProvider(const std::set& filesToIndex) const { @@ -29,6 +30,11 @@ bool SourceGroup::prepareIndexing() return true; } +bool SourceGroup::allowsPartialClearing() const +{ + return true; +} + std::set SourceGroup::filterToContainedSourceFilePath(const std::set& sourceFilePaths) const { std::set filteredSourceFilePaths; @@ -46,3 +52,50 @@ bool SourceGroup::containsSourceFilePath(const FilePath& sourceFilePath) const { return !filterToContainedSourceFilePath({ sourceFilePath }).empty(); } + +std::set SourceGroup::filterToContainedFilePaths( + const std::set& filePaths, + const std::set& indexedFilePaths, + const std::set& indexedFileOrDirectoryPaths, + const std::vector& excludeFilters) const +{ + std::set containedFilePaths; + + for (const FilePath& filePath : filePaths) + { + bool isInIndexedPaths = false; + + for (const FilePath& indexedFileOrDirectoryPath : indexedFileOrDirectoryPaths) + { + if (indexedFileOrDirectoryPath == filePath || indexedFileOrDirectoryPath.contains(filePath)) + { + isInIndexedPaths = true; + break; + } + } + + if (!isInIndexedPaths && indexedFilePaths.find(filePath) != indexedFilePaths.end()) + { + isInIndexedPaths = true; + } + + if (isInIndexedPaths) + { + for (const FilePathFilter& excludeFilter : excludeFilters) + { + if (excludeFilter.isMatching(filePath)) + { + isInIndexedPaths = false; + break; + } + } + } + + if (isInIndexedPaths) + { + containedFilePaths.insert(filePath); + } + } + + return containedFilePaths; +} diff --git a/src/lib/project/SourceGroup.h b/src/lib/project/SourceGroup.h index 8480a31c..181b6313 100644 --- a/src/lib/project/SourceGroup.h +++ b/src/lib/project/SourceGroup.h @@ -12,6 +12,7 @@ class IndexerCommand; class IndexerCommandProvider; class FilePath; +class FilePathFilter; class SourceGroupSettings; class SourceGroup @@ -20,6 +21,8 @@ public: virtual ~SourceGroup() = default; virtual bool prepareIndexing(); + virtual bool allowsPartialClearing() const; + virtual std::set filterToContainedFilePaths(const std::set& filePaths) const = 0; virtual std::set getAllSourceFilePaths() const = 0; virtual std::shared_ptr getIndexerCommandProvider(const std::set& filesToIndex) const; @@ -34,6 +37,12 @@ public: protected: virtual std::shared_ptr getSourceGroupSettings() = 0; virtual std::shared_ptr getSourceGroupSettings() const = 0; + + std::set filterToContainedFilePaths( + const std::set& filePaths, + const std::set& indexedFilePaths, + const std::set& indexedFileOrDirectoryPaths, + const std::vector& excludeFilters) const; }; #endif // SOURCE_GROUP_H diff --git a/src/lib/project/SourceGroupCustomCommand.cpp b/src/lib/project/SourceGroupCustomCommand.cpp new file mode 100644 index 00000000..047b1480 --- /dev/null +++ b/src/lib/project/SourceGroupCustomCommand.cpp @@ -0,0 +1,72 @@ +#include "SourceGroupCustomCommand.h" + +#include "FileManager.h" +#include "IndexerCommandCustom.h" +#include "ProjectSettings.h" +#include "SourceGroupSettingsCustomCommand.h" +#include "SqliteIndexStorage.h" +#include "utility.h" + +SourceGroupCustomCommand::SourceGroupCustomCommand(std::shared_ptr settings) + : m_settings(settings) +{ +} + +bool SourceGroupCustomCommand::allowsPartialClearing() const +{ + return false; +} + +std::set SourceGroupCustomCommand::filterToContainedFilePaths(const std::set& filePaths) const +{ + return SourceGroup::filterToContainedFilePaths( + filePaths, + std::set(), + utility::toSet(m_settings->getSourcePathsExpandedAndAbsolute()), + m_settings->getExcludeFiltersExpandedAndAbsolute() + ); +} + +std::set SourceGroupCustomCommand::getAllSourceFilePaths() const +{ + FileManager fileManager; + fileManager.update( + m_settings->getSourcePathsExpandedAndAbsolute(), + m_settings->getExcludeFiltersExpandedAndAbsolute(), + m_settings->getSourceExtensions() + ); + return fileManager.getAllSourceFilePaths(); +} + +std::vector> SourceGroupCustomCommand::getIndexerCommands(const std::set& filesToIndex) const +{ + std::wstring customCommand = m_settings->getCustomCommand(); + + customCommand = utility::replace(customCommand, L"$PROJECT_PATH", L'\"' + m_settings->getProjectSettings()->getProjectFilePath().wstr() + L'\"'); + customCommand = utility::replace(customCommand, L"$DB_PATH", L'\"' + m_settings->getProjectSettings()->getTempDBFilePath().wstr() + L'\"'); + customCommand = utility::replace(customCommand, L"$STORAGE_VERSION", L'\"' + std::to_wstring(SqliteIndexStorage::getStorageVersion()) + L'\"'); + + std::vector> indexerCommands; + for (const FilePath& sourcePath: getAllSourceFilePaths()) + { + if (filesToIndex.find(sourcePath) != filesToIndex.end()) + { + std::wstring command = utility::replace(customCommand, L"$SOURCE_PATH", L'\"' + sourcePath.wstr() + L'\"'); + + indexerCommands.push_back(std::make_shared(sourcePath, command)); + } + } + + return indexerCommands; +} + +std::shared_ptr SourceGroupCustomCommand::getSourceGroupSettings() +{ + return m_settings; +} + +std::shared_ptr SourceGroupCustomCommand::getSourceGroupSettings() const +{ + return m_settings; +} + diff --git a/src/lib/project/SourceGroupCustomCommand.h b/src/lib/project/SourceGroupCustomCommand.h new file mode 100644 index 00000000..1fc4c0c6 --- /dev/null +++ b/src/lib/project/SourceGroupCustomCommand.h @@ -0,0 +1,30 @@ +#ifndef SOURCE_GROUP_CUSTOM_COMMAND_H +#define SOURCE_GROUP_CUSTOM_COMMAND_H + +#include +#include +#include + +#include "SourceGroup.h" + +class SourceGroupSettingsCustomCommand; + +class SourceGroupCustomCommand: public SourceGroup +{ +public: + SourceGroupCustomCommand(std::shared_ptr settings); + + bool allowsPartialClearing() const override; + + std::set filterToContainedFilePaths(const std::set& filePaths) const override; + std::set getAllSourceFilePaths() const override; + std::vector> getIndexerCommands(const std::set& filesToIndex) const override; + +private: + std::shared_ptr getSourceGroupSettings() override; + std::shared_ptr getSourceGroupSettings() const override; + + std::shared_ptr m_settings; +}; + +#endif // SOURCE_GROUP_CUSTOM_COMMAND_H diff --git a/src/lib/project/SourceGroupFactoryModuleCustom.cpp b/src/lib/project/SourceGroupFactoryModuleCustom.cpp new file mode 100644 index 00000000..2c72c5a1 --- /dev/null +++ b/src/lib/project/SourceGroupFactoryModuleCustom.cpp @@ -0,0 +1,26 @@ +#include "SourceGroupFactoryModuleCustom.h" + +#include "SourceGroupCustomCommand.h" +#include "SourceGroupSettingsCustomCommand.h" + +bool SourceGroupFactoryModuleCustom::supports(SourceGroupType type) const +{ + switch (type) + { + case SOURCE_GROUP_CUSTOM_COMMAND: + return true; + default: + break; + } + return false; +} + +std::shared_ptr SourceGroupFactoryModuleCustom::createSourceGroup(std::shared_ptr settings) const +{ + std::shared_ptr sourceGroup; + if (std::shared_ptr customSettings = std::dynamic_pointer_cast(settings)) + { + sourceGroup = std::shared_ptr(new SourceGroupCustomCommand(customSettings)); + } + return sourceGroup; +} diff --git a/src/lib/project/SourceGroupFactoryModuleCustom.h b/src/lib/project/SourceGroupFactoryModuleCustom.h new file mode 100644 index 00000000..2dfbebb0 --- /dev/null +++ b/src/lib/project/SourceGroupFactoryModuleCustom.h @@ -0,0 +1,14 @@ +#ifndef SOURCE_GROUP_FACTORY_MODULE_CUSTOM_H +#define SOURCE_GROUP_FACTORY_MODULE_CUSTOM_H + +#include "SourceGroupFactoryModule.h" + +class SourceGroupFactoryModuleCustom + : public SourceGroupFactoryModule +{ +public: + bool supports(SourceGroupType type) const override; + std::shared_ptr createSourceGroup(std::shared_ptr settings) const override; +}; + +#endif // SOURCE_GROUP_FACTORY_MODULE_CUSTOM_H diff --git a/src/lib/settings/LanguageType.cpp b/src/lib/settings/LanguageType.cpp index 2fd76adf..97209d0c 100644 --- a/src/lib/settings/LanguageType.cpp +++ b/src/lib/settings/LanguageType.cpp @@ -10,6 +10,8 @@ std::string languageTypeToString(LanguageType t) return "C++"; case LANGUAGE_JAVA: return "Java"; + case LANGUAGE_CUSTOM: + return "Custom"; case LANGUAGE_UNKNOWN: break; } @@ -30,6 +32,10 @@ LanguageType stringToLanguageType(std::string s) { return LANGUAGE_JAVA; } + else if (s == "Custom") + { + return LANGUAGE_CUSTOM; + } return LANGUAGE_UNKNOWN; } @@ -57,6 +63,8 @@ LanguageType getLanguageTypeForSourceGroupType(SourceGroupType t) return LANGUAGE_JAVA; case SOURCE_GROUP_JAVA_SONARGRAPH: return LANGUAGE_JAVA; + case SOURCE_GROUP_CUSTOM_COMMAND: + return LANGUAGE_CUSTOM; default: break; } diff --git a/src/lib/settings/LanguageType.h b/src/lib/settings/LanguageType.h index 6f317872..543114cc 100644 --- a/src/lib/settings/LanguageType.h +++ b/src/lib/settings/LanguageType.h @@ -10,6 +10,7 @@ enum LanguageType LANGUAGE_CPP, LANGUAGE_C, LANGUAGE_JAVA, + LANGUAGE_CUSTOM, LANGUAGE_UNKNOWN }; diff --git a/src/lib/settings/ProjectSettings.cpp b/src/lib/settings/ProjectSettings.cpp index a1a1c813..93f11eb3 100644 --- a/src/lib/settings/ProjectSettings.cpp +++ b/src/lib/settings/ProjectSettings.cpp @@ -1,11 +1,11 @@ #include "ProjectSettings.h" -#include "Project.h" #include "SettingsMigrationDeleteKey.h" #include "SettingsMigrationLambda.h" #include "SettingsMigrationMoveKey.h" #include "SourceGroupSettingsCEmpty.h" #include "SourceGroupSettingsCppEmpty.h" +#include "SourceGroupSettingsCustomCommand.h" #include "SourceGroupSettingsCxxCdb.h" #include "SourceGroupSettingsCxxCodeblocks.h" #include "SourceGroupSettingsCxxSonargraph.h" @@ -17,6 +17,11 @@ #include "utilityString.h" #include "utilityUuid.h" +const std::wstring ProjectSettings::PROJECT_FILE_EXTENSION = L".srctrlprj"; +const std::wstring ProjectSettings::BOOKMARK_DB_FILE_EXTENSION = L".srctrlbm"; +const std::wstring ProjectSettings::INDEX_DB_FILE_EXTENSION = L".srctrldb"; +const std::wstring ProjectSettings::TEMP_INDEX_DB_FILE_EXTENSION = L".srctrldb_tmp"; + const size_t ProjectSettings::VERSION = 7; LanguageType ProjectSettings::getLanguageOfProject(const FilePath& filePath) @@ -115,7 +120,22 @@ FilePath ProjectSettings::getProjectFilePath() const void ProjectSettings::setProjectFilePath(std::wstring projectName, const FilePath& projectFileLocation) { - setFilePath(projectFileLocation.getConcatenated(L"/" + projectName + Project::PROJECT_FILE_EXTENSION)); + setFilePath(projectFileLocation.getConcatenated(L"/" + projectName + PROJECT_FILE_EXTENSION)); +} + +FilePath ProjectSettings::getDBFilePath() const +{ + return getFilePath().replaceExtension(INDEX_DB_FILE_EXTENSION); +} + +FilePath ProjectSettings::getTempDBFilePath() const +{ + return getFilePath().replaceExtension(TEMP_INDEX_DB_FILE_EXTENSION); +} + +FilePath ProjectSettings::getBookmarkDBFilePath() const +{ + return getFilePath().replaceExtension(BOOKMARK_DB_FILE_EXTENSION); } std::wstring ProjectSettings::getProjectName() const @@ -172,6 +192,9 @@ std::vector> ProjectSettings::getAllSourceG case SOURCE_GROUP_JAVA_SONARGRAPH: settings = std::make_shared(id, this); break; + case SOURCE_GROUP_CUSTOM_COMMAND: + settings = std::make_shared(id, this); + break; default: continue; } @@ -356,7 +379,7 @@ SettingsMigrator ProjectSettings::getMigrations() const case LANGUAGE_JAVA: languageName = "java"; break; - case LANGUAGE_UNKNOWN: + default: continue; } diff --git a/src/lib/settings/ProjectSettings.h b/src/lib/settings/ProjectSettings.h index cf456af1..eabca933 100644 --- a/src/lib/settings/ProjectSettings.h +++ b/src/lib/settings/ProjectSettings.h @@ -14,6 +14,11 @@ class ProjectSettings : public Settings { public: + static const std::wstring PROJECT_FILE_EXTENSION; + static const std::wstring BOOKMARK_DB_FILE_EXTENSION; + static const std::wstring INDEX_DB_FILE_EXTENSION; + static const std::wstring TEMP_INDEX_DB_FILE_EXTENSION; + static const size_t VERSION; static LanguageType getLanguageOfProject(const FilePath& filePath); @@ -31,6 +36,10 @@ public: FilePath getProjectFilePath() const; void setProjectFilePath(std::wstring projectName, const FilePath& projectFileLocation); + FilePath getDBFilePath() const; + FilePath getTempDBFilePath() const; + FilePath getBookmarkDBFilePath() const; + std::wstring getProjectName() const; FilePath getProjectDirectoryPath() const; diff --git a/src/lib/settings/SourceGroupSettings.cpp b/src/lib/settings/SourceGroupSettings.cpp index 2b615d57..d6e61d65 100644 --- a/src/lib/settings/SourceGroupSettings.cpp +++ b/src/lib/settings/SourceGroupSettings.cpp @@ -88,6 +88,11 @@ void SourceGroupSettings::setStatus(SourceGroupStatusType status) m_status = status; } +const ProjectSettings* SourceGroupSettings::getProjectSettings() const +{ + return m_projectSettings; +} + FilePath SourceGroupSettings::getProjectDirectoryPath() const { return m_projectSettings->getProjectDirectoryPath(); diff --git a/src/lib/settings/SourceGroupSettings.h b/src/lib/settings/SourceGroupSettings.h index b595f8ff..0f0152fb 100644 --- a/src/lib/settings/SourceGroupSettings.h +++ b/src/lib/settings/SourceGroupSettings.h @@ -5,14 +5,15 @@ #include #include "LanguageType.h" +#include "SourceGroupSettingsBase.h" #include "SourceGroupStatusType.h" #include "SourceGroupType.h" class ConfigManager; class FilePath; -class ProjectSettings; class SourceGroupSettings + : virtual public SourceGroupSettingsBase { public: static const size_t s_version; @@ -40,7 +41,9 @@ public: SourceGroupStatusType getStatus() const; void setStatus(SourceGroupStatusType status); + const ProjectSettings* getProjectSettings() const override; FilePath getProjectDirectoryPath() const; + FilePath makePathExpandedAndAbsolute(const FilePath& path) const; std::vector makePathsExpandedAndAbsolute(const std::vector& paths) const; diff --git a/src/lib/settings/SourceGroupSettingsBase.h b/src/lib/settings/SourceGroupSettingsBase.h new file mode 100644 index 00000000..4d2f2ef7 --- /dev/null +++ b/src/lib/settings/SourceGroupSettingsBase.h @@ -0,0 +1,14 @@ +#ifndef SOURCE_GROUP_SETTINGS_BASE_H +#define SOURCE_GROUP_SETTINGS_BASE_H + +class ProjectSettings; + +class SourceGroupSettingsBase +{ +public: + virtual ~SourceGroupSettingsBase() = default; + + virtual const ProjectSettings* getProjectSettings() const = 0; +}; + +#endif // SOURCE_GROUP_SETTINGS_BASE_H diff --git a/src/lib/settings/SourceGroupSettingsCEmpty.cpp b/src/lib/settings/SourceGroupSettingsCEmpty.cpp index 245979b2..1163bc1d 100644 --- a/src/lib/settings/SourceGroupSettingsCEmpty.cpp +++ b/src/lib/settings/SourceGroupSettingsCEmpty.cpp @@ -51,11 +51,6 @@ bool SourceGroupSettingsCEmpty::equals(std::shared_ptr othe ); } -const ProjectSettings* SourceGroupSettingsCEmpty::getProjectSettings() const -{ - return m_projectSettings; -} - std::vector SourceGroupSettingsCEmpty::getDefaultSourceExtensions() const { return { L".c" }; diff --git a/src/lib/settings/SourceGroupSettingsCEmpty.h b/src/lib/settings/SourceGroupSettingsCEmpty.h index c4553714..b406709e 100644 --- a/src/lib/settings/SourceGroupSettingsCEmpty.h +++ b/src/lib/settings/SourceGroupSettingsCEmpty.h @@ -27,7 +27,6 @@ public: bool equals(std::shared_ptr other) const override; private: - const ProjectSettings* getProjectSettings() const override; std::vector getDefaultSourceExtensions() const override; }; diff --git a/src/lib/settings/SourceGroupSettingsCppEmpty.cpp b/src/lib/settings/SourceGroupSettingsCppEmpty.cpp index 11b6dc91..be9280a7 100644 --- a/src/lib/settings/SourceGroupSettingsCppEmpty.cpp +++ b/src/lib/settings/SourceGroupSettingsCppEmpty.cpp @@ -51,14 +51,9 @@ bool SourceGroupSettingsCppEmpty::equals(std::shared_ptr ot ); } -const ProjectSettings* SourceGroupSettingsCppEmpty::getProjectSettings() const -{ - return m_projectSettings; -} - std::vector SourceGroupSettingsCppEmpty::getDefaultSourceExtensions() const { - return { + return { L".cpp", L".cxx", L".cc" diff --git a/src/lib/settings/SourceGroupSettingsCppEmpty.h b/src/lib/settings/SourceGroupSettingsCppEmpty.h index 814fcea8..a62c5b74 100644 --- a/src/lib/settings/SourceGroupSettingsCppEmpty.h +++ b/src/lib/settings/SourceGroupSettingsCppEmpty.h @@ -27,7 +27,6 @@ public: bool equals(std::shared_ptr other) const override; private: - const ProjectSettings* getProjectSettings() const override; std::vector getDefaultSourceExtensions() const override; }; diff --git a/src/lib/settings/SourceGroupSettingsCustomCommand.cpp b/src/lib/settings/SourceGroupSettingsCustomCommand.cpp new file mode 100644 index 00000000..de8db93b --- /dev/null +++ b/src/lib/settings/SourceGroupSettingsCustomCommand.cpp @@ -0,0 +1,71 @@ +#include "SourceGroupSettingsCustomCommand.h" + +#include "ConfigManager.h" +#include "FilePath.h" + +SourceGroupSettingsCustomCommand::SourceGroupSettingsCustomCommand( + const std::string& id, const ProjectSettings* projectSettings +) + : SourceGroupSettings(id, SOURCE_GROUP_CUSTOM_COMMAND, projectSettings) +{ +} + +std::shared_ptr SourceGroupSettingsCustomCommand::createCopy() const +{ + return std::make_shared(*this); +} + +void SourceGroupSettingsCustomCommand::load(std::shared_ptr config) +{ + SourceGroupSettings::load(config); + + const std::string key = s_keyPrefix + getId(); + + SourceGroupSettingsWithSourceExtensions::load(config, key); + SourceGroupSettingsWithSourcePaths::load(config, key); + SourceGroupSettingsWithExcludeFilters::load(config, key); + + setCustomCommand(config->getValueOrDefault(key + "/custom_command", std::wstring())); +} + +void SourceGroupSettingsCustomCommand::save(std::shared_ptr config) +{ + SourceGroupSettings::save(config); + + const std::string key = s_keyPrefix + getId(); + + SourceGroupSettingsWithSourceExtensions::save(config, key); + SourceGroupSettingsWithSourcePaths::save(config, key); + SourceGroupSettingsWithExcludeFilters::save(config, key); + + config->setValue(key + "/custom_command", getCustomCommand()); +} + +bool SourceGroupSettingsCustomCommand::equals(std::shared_ptr other) const +{ + std::shared_ptr otherCustom = + std::dynamic_pointer_cast(other); + + return ( + otherCustom && + SourceGroupSettings::equals(other) && + SourceGroupSettingsWithSourceExtensions::equals(otherCustom) && + SourceGroupSettingsWithSourcePaths::equals(otherCustom) && + SourceGroupSettingsWithExcludeFilters::equals(otherCustom) + ); +} + +const std::wstring& SourceGroupSettingsCustomCommand::getCustomCommand() const +{ + return m_customCommand; +} + +void SourceGroupSettingsCustomCommand::setCustomCommand(const std::wstring& customCommand) +{ + m_customCommand = customCommand; +} + +std::vector SourceGroupSettingsCustomCommand::getDefaultSourceExtensions() const +{ + return {}; +} diff --git a/src/lib/settings/SourceGroupSettingsCustomCommand.h b/src/lib/settings/SourceGroupSettingsCustomCommand.h new file mode 100644 index 00000000..ce8ca801 --- /dev/null +++ b/src/lib/settings/SourceGroupSettingsCustomCommand.h @@ -0,0 +1,34 @@ +#ifndef SOURCE_GROUP_SETTINGS_CUSTOM_COMMAND_H +#define SOURCE_GROUP_SETTINGS_CUSTOM_COMMAND_H + +#include "SourceGroupSettings.h" +#include "SourceGroupSettingsWithExcludeFilters.h" +#include "SourceGroupSettingsWithSourceExtensions.h" +#include "SourceGroupSettingsWithSourcePaths.h" + +class SourceGroupSettingsCustomCommand + : public SourceGroupSettings + , public SourceGroupSettingsWithExcludeFilters + , public SourceGroupSettingsWithSourceExtensions + , public SourceGroupSettingsWithSourcePaths +{ +public: + SourceGroupSettingsCustomCommand(const std::string& id, const ProjectSettings* projectSettings); + + std::shared_ptr createCopy() const override; + + void load(std::shared_ptr config) override; + void save(std::shared_ptr config) override; + + bool equals(std::shared_ptr other) const override; + + const std::wstring& getCustomCommand() const; + void setCustomCommand(const std::wstring& customCommand); + +private: + std::vector getDefaultSourceExtensions() const override; + + std::wstring m_customCommand; +}; + +#endif // SOURCE_GROUP_SETTINGS_CUSTOM_COMMAND_H diff --git a/src/lib/settings/SourceGroupSettingsCxxCdb.cpp b/src/lib/settings/SourceGroupSettingsCxxCdb.cpp index 2e6627b0..478fbd62 100644 --- a/src/lib/settings/SourceGroupSettingsCxxCdb.cpp +++ b/src/lib/settings/SourceGroupSettingsCxxCdb.cpp @@ -65,8 +65,3 @@ void SourceGroupSettingsCxxCdb::setCompilationDatabasePath(const FilePath& compi { m_compilationDatabasePath = compilationDatabasePath; } - -const ProjectSettings* SourceGroupSettingsCxxCdb::getProjectSettings() const -{ - return m_projectSettings; -} diff --git a/src/lib/settings/SourceGroupSettingsCxxCdb.h b/src/lib/settings/SourceGroupSettingsCxxCdb.h index 4121d67a..6631e403 100644 --- a/src/lib/settings/SourceGroupSettingsCxxCdb.h +++ b/src/lib/settings/SourceGroupSettingsCxxCdb.h @@ -26,8 +26,6 @@ public: void setCompilationDatabasePath(const FilePath& compilationDatabasePath); private: - const ProjectSettings* getProjectSettings() const override; - FilePath m_compilationDatabasePath; }; diff --git a/src/lib/settings/SourceGroupSettingsCxxCodeblocks.cpp b/src/lib/settings/SourceGroupSettingsCxxCodeblocks.cpp index 2d6da7d9..3b556166 100644 --- a/src/lib/settings/SourceGroupSettingsCxxCodeblocks.cpp +++ b/src/lib/settings/SourceGroupSettingsCxxCodeblocks.cpp @@ -24,7 +24,7 @@ void SourceGroupSettingsCxxCodeblocks::load(std::shared_ptr SourceGroupSettingsWithExcludeFilters::load(config, key); SourceGroupSettingsWithIndexedHeaderPaths::load(config, key); SourceGroupSettingsWithSourceExtensions::load(config, key); - + setCodeblocksProjectPath(config->getValueOrDefault(key + "/codeblocks_project_path", FilePath(L""))); } @@ -74,11 +74,6 @@ void SourceGroupSettingsCxxCodeblocks::setCodeblocksProjectPath(const FilePath& m_codeblocksProjectPath = compilationDatabasePath; } -const ProjectSettings* SourceGroupSettingsCxxCodeblocks::getProjectSettings() const -{ - return m_projectSettings; -} - std::vector SourceGroupSettingsCxxCodeblocks::getDefaultSourceExtensions() const { return { diff --git a/src/lib/settings/SourceGroupSettingsCxxCodeblocks.h b/src/lib/settings/SourceGroupSettingsCxxCodeblocks.h index 642b1a78..076f9155 100644 --- a/src/lib/settings/SourceGroupSettingsCxxCodeblocks.h +++ b/src/lib/settings/SourceGroupSettingsCxxCodeblocks.h @@ -31,7 +31,6 @@ public: void setCodeblocksProjectPath(const FilePath& compilationDatabasePath); private: - const ProjectSettings* getProjectSettings() const override; std::vector getDefaultSourceExtensions() const override; FilePath m_codeblocksProjectPath; diff --git a/src/lib/settings/SourceGroupSettingsCxxSonargraph.cpp b/src/lib/settings/SourceGroupSettingsCxxSonargraph.cpp index d9ad14db..5c6f35f1 100644 --- a/src/lib/settings/SourceGroupSettingsCxxSonargraph.cpp +++ b/src/lib/settings/SourceGroupSettingsCxxSonargraph.cpp @@ -44,8 +44,3 @@ bool SourceGroupSettingsCxxSonargraph::equals(std::shared_ptr config) override; bool equals(std::shared_ptr other) const override; - -private: - const ProjectSettings* getProjectSettings() const override; }; #endif // SOURCE_GROUP_SETTINGS_CXX_SONARGRAPH_H diff --git a/src/lib/settings/SourceGroupSettingsJavaEmpty.cpp b/src/lib/settings/SourceGroupSettingsJavaEmpty.cpp index 1728ca3e..a4471557 100644 --- a/src/lib/settings/SourceGroupSettingsJavaEmpty.cpp +++ b/src/lib/settings/SourceGroupSettingsJavaEmpty.cpp @@ -41,8 +41,3 @@ bool SourceGroupSettingsJavaEmpty::equals(std::shared_ptr o SourceGroupSettingsWithClasspath::equals(otherJava) ); } - -const ProjectSettings* SourceGroupSettingsJavaEmpty::getProjectSettings() const -{ - return m_projectSettings; -} diff --git a/src/lib/settings/SourceGroupSettingsJavaEmpty.h b/src/lib/settings/SourceGroupSettingsJavaEmpty.h index b43f72a9..933dc916 100644 --- a/src/lib/settings/SourceGroupSettingsJavaEmpty.h +++ b/src/lib/settings/SourceGroupSettingsJavaEmpty.h @@ -19,9 +19,6 @@ public: void save(std::shared_ptr config) override; bool equals(std::shared_ptr other) const override; - -private: - const ProjectSettings* getProjectSettings() const override; }; #endif // SOURCE_GROUP_SETTINGS_JAVA_EMPTY_H diff --git a/src/lib/settings/SourceGroupSettingsJavaGradle.cpp b/src/lib/settings/SourceGroupSettingsJavaGradle.cpp index 95d327c1..2e0cadf3 100644 --- a/src/lib/settings/SourceGroupSettingsJavaGradle.cpp +++ b/src/lib/settings/SourceGroupSettingsJavaGradle.cpp @@ -90,8 +90,3 @@ void SourceGroupSettingsJavaGradle::setShouldIndexGradleTests(bool value) { m_shouldIndexGradleTests = value; } - -const ProjectSettings* SourceGroupSettingsJavaGradle::getProjectSettings() const -{ - return m_projectSettings; -} diff --git a/src/lib/settings/SourceGroupSettingsJavaGradle.h b/src/lib/settings/SourceGroupSettingsJavaGradle.h index f8de530f..69ac07b2 100644 --- a/src/lib/settings/SourceGroupSettingsJavaGradle.h +++ b/src/lib/settings/SourceGroupSettingsJavaGradle.h @@ -29,8 +29,6 @@ public: void setShouldIndexGradleTests(bool value); private: - const ProjectSettings* getProjectSettings() const override; - FilePath m_gradleProjectFilePath; FilePath m_gradleDependenciesDirectory; bool m_shouldIndexGradleTests; diff --git a/src/lib/settings/SourceGroupSettingsJavaMaven.cpp b/src/lib/settings/SourceGroupSettingsJavaMaven.cpp index 86374786..7aaf683d 100644 --- a/src/lib/settings/SourceGroupSettingsJavaMaven.cpp +++ b/src/lib/settings/SourceGroupSettingsJavaMaven.cpp @@ -90,8 +90,3 @@ void SourceGroupSettingsJavaMaven::setShouldIndexMavenTests(bool value) { m_shouldIndexMavenTests = value; } - -const ProjectSettings* SourceGroupSettingsJavaMaven::getProjectSettings() const -{ - return m_projectSettings; -} diff --git a/src/lib/settings/SourceGroupSettingsJavaMaven.h b/src/lib/settings/SourceGroupSettingsJavaMaven.h index 43d2ab75..9483719c 100644 --- a/src/lib/settings/SourceGroupSettingsJavaMaven.h +++ b/src/lib/settings/SourceGroupSettingsJavaMaven.h @@ -29,8 +29,6 @@ public: void setShouldIndexMavenTests(bool value); private: - const ProjectSettings* getProjectSettings() const override; - FilePath m_mavenProjectFilePath; FilePath m_mavenDependenciesDirectory; bool m_shouldIndexMavenTests; diff --git a/src/lib/settings/SourceGroupSettingsJavaSonargraph.cpp b/src/lib/settings/SourceGroupSettingsJavaSonargraph.cpp index b5c70992..1e5acd86 100644 --- a/src/lib/settings/SourceGroupSettingsJavaSonargraph.cpp +++ b/src/lib/settings/SourceGroupSettingsJavaSonargraph.cpp @@ -44,8 +44,3 @@ bool SourceGroupSettingsJavaSonargraph::equals(std::shared_ptr config) override; bool equals(std::shared_ptr other) const override; - -private: - const ProjectSettings* getProjectSettings() const override; }; #endif // SOURCE_GROUP_SETTINGS_JAVA_SONARGRAPH_H diff --git a/src/lib/settings/SourceGroupSettingsWithCStandard.h b/src/lib/settings/SourceGroupSettingsWithCStandard.h index 5dfc67e9..d33176e5 100644 --- a/src/lib/settings/SourceGroupSettingsWithCStandard.h +++ b/src/lib/settings/SourceGroupSettingsWithCStandard.h @@ -5,10 +5,12 @@ #include #include +#include "SourceGroupSettingsBase.h" + class ConfigManager; -class ProjectSettings; class SourceGroupSettingsWithCStandard + : virtual public SourceGroupSettingsBase { public: static std::wstring getDefaultCStandardStatic(); @@ -28,7 +30,6 @@ protected: void save(std::shared_ptr config, const std::string& key); private: - virtual const ProjectSettings* getProjectSettings() const = 0; std::wstring getDefaultCStandard() const; std::wstring m_cStandard; diff --git a/src/lib/settings/SourceGroupSettingsWithClasspath.h b/src/lib/settings/SourceGroupSettingsWithClasspath.h index bfd1681d..f4fc1793 100644 --- a/src/lib/settings/SourceGroupSettingsWithClasspath.h +++ b/src/lib/settings/SourceGroupSettingsWithClasspath.h @@ -6,11 +6,12 @@ #include #include "FilePath.h" +#include "SourceGroupSettingsBase.h" class ConfigManager; -class ProjectSettings; class SourceGroupSettingsWithClasspath + : virtual public SourceGroupSettingsBase { public: SourceGroupSettingsWithClasspath(); @@ -30,8 +31,6 @@ protected: void save(std::shared_ptr config, const std::string& key); private: - virtual const ProjectSettings* getProjectSettings() const = 0; - std::vector m_classpath; bool m_useJreSystemLibrary; }; diff --git a/src/lib/settings/SourceGroupSettingsWithCppStandard.h b/src/lib/settings/SourceGroupSettingsWithCppStandard.h index f282c454..a06d8cf7 100644 --- a/src/lib/settings/SourceGroupSettingsWithCppStandard.h +++ b/src/lib/settings/SourceGroupSettingsWithCppStandard.h @@ -5,10 +5,12 @@ #include #include +#include "SourceGroupSettingsBase.h" + class ConfigManager; -class ProjectSettings; class SourceGroupSettingsWithCppStandard + : virtual public SourceGroupSettingsBase { public: static std::wstring getDefaultCppStandardStatic(); @@ -28,7 +30,6 @@ protected: void save(std::shared_ptr config, const std::string& key); private: - virtual const ProjectSettings* getProjectSettings() const = 0; std::wstring getDefaultCppStandard() const; std::wstring m_cppStandard; diff --git a/src/lib/settings/SourceGroupSettingsWithCxxCrossCompilationOptions.h b/src/lib/settings/SourceGroupSettingsWithCxxCrossCompilationOptions.h index fad5f6f1..24a34eac 100644 --- a/src/lib/settings/SourceGroupSettingsWithCxxCrossCompilationOptions.h +++ b/src/lib/settings/SourceGroupSettingsWithCxxCrossCompilationOptions.h @@ -5,10 +5,12 @@ #include #include +#include "SourceGroupSettingsBase.h" + class ConfigManager; -class ProjectSettings; class SourceGroupSettingsWithCxxCrossCompilationOptions + : virtual public SourceGroupSettingsBase { public: static std::vector getAvailableArchTypes(); @@ -43,8 +45,6 @@ protected: void save(std::shared_ptr config, const std::string& key); private: - virtual const ProjectSettings* getProjectSettings() const = 0; - bool m_targetOptionsEnabled; std::wstring m_targetArch; std::wstring m_targetVendor; diff --git a/src/lib/settings/SourceGroupSettingsWithExcludeFilters.h b/src/lib/settings/SourceGroupSettingsWithExcludeFilters.h index b4659419..fe46dbdc 100644 --- a/src/lib/settings/SourceGroupSettingsWithExcludeFilters.h +++ b/src/lib/settings/SourceGroupSettingsWithExcludeFilters.h @@ -5,28 +5,29 @@ #include #include +#include "SourceGroupSettingsBase.h" + class ConfigManager; class FilePathFilter; -class ProjectSettings; class SourceGroupSettingsWithExcludeFilters + : virtual public SourceGroupSettingsBase { public: SourceGroupSettingsWithExcludeFilters(); virtual ~SourceGroupSettingsWithExcludeFilters() = default; - + bool equals(std::shared_ptr other) const; std::vector getExcludeFilterStrings() const; std::vector getExcludeFiltersExpandedAndAbsolute() const; void setExcludeFilterStrings(const std::vector& excludeFilters); - + protected: void load(std::shared_ptr config, const std::string& key); void save(std::shared_ptr config, const std::string& key); private: - virtual const ProjectSettings* getProjectSettings() const = 0; std::vector getFiltersExpandedAndAbsolute(const std::vector& filterStrings) const; std::vector m_excludeFilters; diff --git a/src/lib/settings/SourceGroupSettingsWithIndexedHeaderPaths.h b/src/lib/settings/SourceGroupSettingsWithIndexedHeaderPaths.h index cae9604b..11331a60 100644 --- a/src/lib/settings/SourceGroupSettingsWithIndexedHeaderPaths.h +++ b/src/lib/settings/SourceGroupSettingsWithIndexedHeaderPaths.h @@ -5,11 +5,13 @@ #include #include +#include "SourceGroupSettingsBase.h" + class ConfigManager; class FilePath; -class ProjectSettings; class SourceGroupSettingsWithIndexedHeaderPaths + : virtual public SourceGroupSettingsBase { public: SourceGroupSettingsWithIndexedHeaderPaths(); @@ -26,8 +28,6 @@ protected: void save(std::shared_ptr config, const std::string& key); private: - virtual const ProjectSettings* getProjectSettings() const = 0; - std::vector m_indexedHeaderPaths; }; diff --git a/src/lib/settings/SourceGroupSettingsWithJavaStandard.h b/src/lib/settings/SourceGroupSettingsWithJavaStandard.h index 2a6b3468..bf314894 100644 --- a/src/lib/settings/SourceGroupSettingsWithJavaStandard.h +++ b/src/lib/settings/SourceGroupSettingsWithJavaStandard.h @@ -5,10 +5,12 @@ #include #include +#include "SourceGroupSettingsBase.h" + class ConfigManager; -class ProjectSettings; class SourceGroupSettingsWithJavaStandard + : virtual public SourceGroupSettingsBase { public: static std::wstring getDefaultJavaStandardStatic(); @@ -28,7 +30,6 @@ protected: void save(std::shared_ptr config, const std::string& key); private: - virtual const ProjectSettings* getProjectSettings() const = 0; std::wstring getDefaultJavaStandard() const; std::wstring m_javaStandard; diff --git a/src/lib/settings/SourceGroupSettingsWithSonargraphProjectPath.h b/src/lib/settings/SourceGroupSettingsWithSonargraphProjectPath.h index c19fd7bd..5b09f5dc 100644 --- a/src/lib/settings/SourceGroupSettingsWithSonargraphProjectPath.h +++ b/src/lib/settings/SourceGroupSettingsWithSonargraphProjectPath.h @@ -4,12 +4,13 @@ #include #include +#include "SourceGroupSettingsBase.h" #include "FilePath.h" class ConfigManager; -class ProjectSettings; class SourceGroupSettingsWithSonargraphProjectPath + : virtual public SourceGroupSettingsBase { public: SourceGroupSettingsWithSonargraphProjectPath(); @@ -26,8 +27,6 @@ protected: void save(std::shared_ptr config, const std::string& key); private: - virtual const ProjectSettings* getProjectSettings() const = 0; - FilePath m_sonargraphProjectPath; }; diff --git a/src/lib/settings/SourceGroupSettingsWithSourceExtensions.h b/src/lib/settings/SourceGroupSettingsWithSourceExtensions.h index 7f9d9da3..fd79dddb 100644 --- a/src/lib/settings/SourceGroupSettingsWithSourceExtensions.h +++ b/src/lib/settings/SourceGroupSettingsWithSourceExtensions.h @@ -5,27 +5,28 @@ #include #include +#include "SourceGroupSettingsBase.h" + class ConfigManager; class FilePath; -class ProjectSettings; class SourceGroupSettingsWithSourceExtensions + : virtual public SourceGroupSettingsBase { public: SourceGroupSettingsWithSourceExtensions(); virtual ~SourceGroupSettingsWithSourceExtensions() = default; - + bool equals(std::shared_ptr other) const; std::vector getSourceExtensions() const; void setSourceExtensions(const std::vector& sourceExtensions); - + protected: void load(std::shared_ptr config, const std::string& key); void save(std::shared_ptr config, const std::string& key); private: - virtual const ProjectSettings* getProjectSettings() const = 0; virtual std::vector getDefaultSourceExtensions() const = 0; std::vector m_sourceExtensions; diff --git a/src/lib/settings/SourceGroupSettingsWithSourcePaths.h b/src/lib/settings/SourceGroupSettingsWithSourcePaths.h index c8ac7712..1db680dd 100644 --- a/src/lib/settings/SourceGroupSettingsWithSourcePaths.h +++ b/src/lib/settings/SourceGroupSettingsWithSourcePaths.h @@ -5,16 +5,18 @@ #include #include +#include "SourceGroupSettingsBase.h" + class ConfigManager; class FilePath; -class ProjectSettings; class SourceGroupSettingsWithSourcePaths + : virtual public SourceGroupSettingsBase { public: SourceGroupSettingsWithSourcePaths(); virtual ~SourceGroupSettingsWithSourcePaths() = default; - + bool equals(std::shared_ptr other) const; std::vector getSourcePaths() const; @@ -26,8 +28,6 @@ protected: void save(std::shared_ptr config, const std::string& key); private: - virtual const ProjectSettings* getProjectSettings() const = 0; - std::vector m_sourcePaths; }; diff --git a/src/lib/settings/SourceGroupType.cpp b/src/lib/settings/SourceGroupType.cpp index e10d1bdb..00273ed5 100644 --- a/src/lib/settings/SourceGroupType.cpp +++ b/src/lib/settings/SourceGroupType.cpp @@ -24,6 +24,8 @@ std::string sourceGroupTypeToString(SourceGroupType v) return "Java Source Group from Gradle"; case SOURCE_GROUP_JAVA_SONARGRAPH: return "Java from Sonargraph"; + case SOURCE_GROUP_CUSTOM_COMMAND: + return "Custom Command Source Group"; case SOURCE_GROUP_UNKNOWN: break; } @@ -54,6 +56,8 @@ std::string sourceGroupTypeToProjectSetupString(SourceGroupType v) return "Java Source Group from Gradle"; case SOURCE_GROUP_JAVA_SONARGRAPH: return "Java from Sonargraph"; + case SOURCE_GROUP_CUSTOM_COMMAND: + return "Custom Command Source Group"; case SOURCE_GROUP_UNKNOWN: break; } @@ -102,6 +106,10 @@ SourceGroupType stringToSourceGroupType(const std::string& v) { return SOURCE_GROUP_JAVA_SONARGRAPH; } + else if (v == sourceGroupTypeToString(SOURCE_GROUP_CUSTOM_COMMAND)) + { + return SOURCE_GROUP_CUSTOM_COMMAND; + } return SOURCE_GROUP_UNKNOWN; } diff --git a/src/lib/settings/SourceGroupType.h b/src/lib/settings/SourceGroupType.h index 91e42704..0a77a9f3 100644 --- a/src/lib/settings/SourceGroupType.h +++ b/src/lib/settings/SourceGroupType.h @@ -15,6 +15,7 @@ enum SourceGroupType SOURCE_GROUP_JAVA_MAVEN, SOURCE_GROUP_JAVA_GRADLE, SOURCE_GROUP_JAVA_SONARGRAPH, + SOURCE_GROUP_CUSTOM_COMMAND, SOURCE_GROUP_UNKNOWN }; diff --git a/src/lib/utility/file/FileSystem.cpp b/src/lib/utility/file/FileSystem.cpp index 4745a250..f644cd93 100644 --- a/src/lib/utility/file/FileSystem.cpp +++ b/src/lib/utility/file/FileSystem.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include "utilityString.h" @@ -196,6 +197,7 @@ TimeStamp FileSystem::getLastWriteTime(const FilePath& filePath) { std::time_t t = boost::filesystem::last_write_time(filePath.getPath()); lastWriteTime = boost::posix_time::from_time_t(t); + lastWriteTime = boost::date_time::c_local_adjustor::utc_to_local(lastWriteTime); } return TimeStamp(lastWriteTime); } diff --git a/src/lib/utility/messaging/type/indexing/MessageIndexingInterrupted.h b/src/lib/utility/messaging/type/indexing/MessageIndexingInterrupted.h index 3c425686..48419434 100644 --- a/src/lib/utility/messaging/type/indexing/MessageIndexingInterrupted.h +++ b/src/lib/utility/messaging/type/indexing/MessageIndexingInterrupted.h @@ -11,6 +11,11 @@ public: { return "MessageIndexingInterrupted"; } + + MessageIndexingInterrupted() + { + setSendAsTask(false); + } }; #endif // MESSAGE_INDEXING_INTERRUPTED_H diff --git a/src/lib_cxx/CMakeLists.txt b/src/lib_cxx/CMakeLists.txt index 98f7f293..d323f881 100644 --- a/src/lib_cxx/CMakeLists.txt +++ b/src/lib_cxx/CMakeLists.txt @@ -76,7 +76,7 @@ add_files( data/parser/cxx/PreprocessorCallbacks.h data/parser/cxx/utilityClang.cpp data/parser/cxx/utilityClang.h - + project/SourceGroupCxxCdb.cpp project/SourceGroupCxxCdb.h project/SourceGroupCxxCodeblocks.cpp @@ -106,9 +106,7 @@ add_files( utility/IncludeDirective.h utility/IncludeProcessing.cpp utility/IncludeProcessing.h - utility/utilitySourceGroupCxx.cpp - utility/utilitySourceGroupCxx.h - + LanguagePackageCxx.cpp LanguagePackageCxx.h ) diff --git a/src/lib_cxx/project/SourceGroupCxxCdb.cpp b/src/lib_cxx/project/SourceGroupCxxCdb.cpp index 748ec3e6..3632c226 100644 --- a/src/lib_cxx/project/SourceGroupCxxCdb.cpp +++ b/src/lib_cxx/project/SourceGroupCxxCdb.cpp @@ -8,7 +8,6 @@ #include "ApplicationSettings.h" #include "MessageStatus.h" #include "utility.h" -#include "utilitySourceGroupCxx.h" #include "Application.h" SourceGroupCxxCdb::SourceGroupCxxCdb(std::shared_ptr settings) @@ -40,7 +39,7 @@ bool SourceGroupCxxCdb::prepareIndexing() std::set SourceGroupCxxCdb::filterToContainedFilePaths(const std::set& filePaths) const { - return utility::filterToContainedFilePaths( + return SourceGroup::filterToContainedFilePaths( filePaths, getAllSourceFilePaths(), utility::toSet(m_settings->getIndexedHeaderPathsExpandedAndAbsolute()), diff --git a/src/lib_cxx/project/SourceGroupCxxCodeblocks.cpp b/src/lib_cxx/project/SourceGroupCxxCodeblocks.cpp index e1dd5c67..4557460e 100644 --- a/src/lib_cxx/project/SourceGroupCxxCodeblocks.cpp +++ b/src/lib_cxx/project/SourceGroupCxxCodeblocks.cpp @@ -7,7 +7,6 @@ #include "MessageStatus.h" #include "CodeblocksProject.h" #include "utility.h" -#include "utilitySourceGroupCxx.h" #include "Application.h" SourceGroupCxxCodeblocks::SourceGroupCxxCodeblocks(std::shared_ptr settings) @@ -39,7 +38,7 @@ bool SourceGroupCxxCodeblocks::prepareIndexing() std::set SourceGroupCxxCodeblocks::filterToContainedFilePaths(const std::set& filePaths) const { - return utility::filterToContainedFilePaths( + return SourceGroup::filterToContainedFilePaths( filePaths, getAllSourceFilePaths(), utility::toSet(m_settings->getIndexedHeaderPathsExpandedAndAbsolute()), diff --git a/src/lib_cxx/project/SourceGroupCxxEmpty.cpp b/src/lib_cxx/project/SourceGroupCxxEmpty.cpp index 0fd1c6c3..18e91099 100644 --- a/src/lib_cxx/project/SourceGroupCxxEmpty.cpp +++ b/src/lib_cxx/project/SourceGroupCxxEmpty.cpp @@ -9,7 +9,6 @@ #include "SourceGroupSettingsWithCStandard.h" #include "FileManager.h" #include "utility.h" -#include "utilitySourceGroupCxx.h" SourceGroupCxxEmpty::SourceGroupCxxEmpty(std::shared_ptr settings) : m_settings(settings) @@ -33,7 +32,7 @@ std::set SourceGroupCxxEmpty::filterToContainedFilePaths(const std::se excludeFilters = settings->getExcludeFiltersExpandedAndAbsolute(); } - return utility::filterToContainedFilePaths( + return SourceGroup::filterToContainedFilePaths( filePaths, std::set(), utility::toSet(indexedPaths), diff --git a/src/lib_cxx/project/SourceGroupCxxSonargraph.cpp b/src/lib_cxx/project/SourceGroupCxxSonargraph.cpp index d18a8047..6bc24d1e 100644 --- a/src/lib_cxx/project/SourceGroupCxxSonargraph.cpp +++ b/src/lib_cxx/project/SourceGroupCxxSonargraph.cpp @@ -7,7 +7,6 @@ #include "MessageStatus.h" #include "SonargraphProject.h" #include "utility.h" -#include "utilitySourceGroupCxx.h" #include "Application.h" SourceGroupCxxSonargraph::SourceGroupCxxSonargraph(std::shared_ptr settings) @@ -39,7 +38,7 @@ bool SourceGroupCxxSonargraph::prepareIndexing() std::set SourceGroupCxxSonargraph::filterToContainedFilePaths(const std::set& filePaths) const { - return utility::filterToContainedFilePaths( + return SourceGroup::filterToContainedFilePaths( filePaths, getAllSourceFilePaths(), utility::toSet(m_settings->getIndexedHeaderPathsExpandedAndAbsolute()), diff --git a/src/lib_cxx/utility/utilitySourceGroupCxx.cpp b/src/lib_cxx/utility/utilitySourceGroupCxx.cpp deleted file mode 100644 index a34cb6b0..00000000 --- a/src/lib_cxx/utility/utilitySourceGroupCxx.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "utilitySourceGroupCxx.h" - -std::set utility::filterToContainedFilePaths( - const std::set& filePaths, - const std::set& indexedFilePaths, - const std::set& indexedFileOrDirectoryPaths, - const std::vector& excludeFilters) -{ - std::set containedFilePaths; - - for (const FilePath& filePath : filePaths) - { - bool isInIndexedPaths = false; - - for (const FilePath& indexedFileOrDirectoryPath : indexedFileOrDirectoryPaths) - { - if (indexedFileOrDirectoryPath == filePath || indexedFileOrDirectoryPath.contains(filePath)) - { - isInIndexedPaths = true; - break; - } - } - - if (!isInIndexedPaths && indexedFilePaths.find(filePath) != indexedFilePaths.end()) - { - isInIndexedPaths = true; - } - - if (isInIndexedPaths) - { - for (const FilePathFilter& excludeFilter : excludeFilters) - { - if (excludeFilter.isMatching(filePath)) - { - isInIndexedPaths = false; - break; - } - } - } - - if (isInIndexedPaths) - { - containedFilePaths.insert(filePath); - } - } - - return containedFilePaths; -} diff --git a/src/lib_cxx/utility/utilitySourceGroupCxx.h b/src/lib_cxx/utility/utilitySourceGroupCxx.h deleted file mode 100644 index be48d24d..00000000 --- a/src/lib_cxx/utility/utilitySourceGroupCxx.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef UTILITY_SOURCE_GROUP_CXX_H -#define UTILITY_SOURCE_GROUP_CXX_H - -#include -#include - -#include "FilePath.h" -#include "FilePathFilter.h" - -namespace utility -{ - std::set filterToContainedFilePaths( - const std::set& filePaths, - const std::set& indexedFilePaths, - const std::set& indexedFileOrDirectoryPaths, - const std::vector& excludeFilters); -} - -#endif // UTILITY_SOURCE_GROUP_CXX_H diff --git a/src/lib_gui/CMakeLists.txt b/src/lib_gui/CMakeLists.txt index d7b801af..3ba8f6e8 100644 --- a/src/lib_gui/CMakeLists.txt +++ b/src/lib_gui/CMakeLists.txt @@ -203,6 +203,8 @@ add_files( qt/window/project_wizzard/QtProjectWizzardContentCrossCompilationOptions.h qt/window/project_wizzard/QtProjectWizzardContentCStandard.cpp qt/window/project_wizzard/QtProjectWizzardContentCStandard.h + qt/window/project_wizzard/QtProjectWizzardContentCustomCommand.cpp + qt/window/project_wizzard/QtProjectWizzardContentCustomCommand.h qt/window/project_wizzard/QtProjectWizzardContentExtensions.cpp qt/window/project_wizzard/QtProjectWizzardContentExtensions.h qt/window/project_wizzard/QtProjectWizzardContentFlags.cpp diff --git a/src/lib_gui/qt/view/QtDialogView.cpp b/src/lib_gui/qt/view/QtDialogView.cpp index 2d3c8ed5..17f0cbe1 100644 --- a/src/lib_gui/qt/view/QtDialogView.cpp +++ b/src/lib_gui/qt/view/QtDialogView.cpp @@ -266,6 +266,23 @@ void QtDialogView::updateIndexingDialog( ); } +void QtDialogView::updateCustomIndexingDialog( + size_t startedFileCount, size_t finishedFileCount, size_t totalFileCount, const std::vector& sourcePaths) +{ + updateIndexingDialog(startedFileCount, finishedFileCount, totalFileCount, sourcePaths); + + m_onQtThread( + [=]() + { + QtIndexingDialog* window = dynamic_cast(m_windowStack.getTopWindow()); + if (window && window->getType() == QtIndexingDialog::DIALOG_INDEXING) + { + window->updateTitle("Executing Commands"); + } + } + ); +} + DatabasePolicy QtDialogView::finishedIndexingDialog( size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo, bool interrupted) diff --git a/src/lib_gui/qt/view/QtDialogView.h b/src/lib_gui/qt/view/QtDialogView.h index 548d04e0..0077210c 100644 --- a/src/lib_gui/qt/view/QtDialogView.h +++ b/src/lib_gui/qt/view/QtDialogView.h @@ -42,6 +42,8 @@ public: std::function onStartIndexing, std::function onCancelIndexing) override; void updateIndexingDialog( size_t startedFileCount, size_t finishedFileCount, size_t totalFileCount, const std::vector& sourcePaths) override; + void updateCustomIndexingDialog( + size_t startedFileCount, size_t finishedFileCount, size_t totalFileCount, const std::vector& sourcePaths) override; DatabasePolicy finishedIndexingDialog( size_t indexedFileCount, size_t totalIndexedFileCount, size_t completedFileCount, size_t totalFileCount, float time, ErrorCountInfo errorInfo, bool interrupted) override; diff --git a/src/lib_gui/qt/view/QtStatusView.cpp b/src/lib_gui/qt/view/QtStatusView.cpp index b45b18fb..c27cb7f9 100644 --- a/src/lib_gui/qt/view/QtStatusView.cpp +++ b/src/lib_gui/qt/view/QtStatusView.cpp @@ -124,6 +124,11 @@ void QtStatusView::addStatus(const std::vector& status) QString statusType = (s.type == StatusType::STATUS_ERROR ? "ERROR" : "INFO"); m_model->setItem(rowNumber, STATUSVIEW_COLUMN::TYPE, new QStandardItem(statusType)); m_model->setItem(rowNumber, STATUSVIEW_COLUMN::STATUS, new QStandardItem(QString::fromStdWString(s.message))); + + if (s.type == StatusType::STATUS_ERROR) + { + m_model->item(rowNumber, STATUSVIEW_COLUMN::TYPE)->setForeground(QBrush(Qt::red)); + } } m_table->updateRows(); diff --git a/src/lib_gui/qt/window/QtIndexingDialog.cpp b/src/lib_gui/qt/window/QtIndexingDialog.cpp index 4060b481..6240a4ce 100644 --- a/src/lib_gui/qt/window/QtIndexingDialog.cpp +++ b/src/lib_gui/qt/window/QtIndexingDialog.cpp @@ -294,6 +294,14 @@ void QtIndexingDialog::setupProgress(bool hideable) finishSetup(); } +void QtIndexingDialog::updateTitle(const QString& title) +{ + if (m_title) + { + m_title->setText(title); + } +} + void QtIndexingDialog::updateMessage(const QString& message) { if (m_messageLabel) diff --git a/src/lib_gui/qt/window/QtIndexingDialog.h b/src/lib_gui/qt/window/QtIndexingDialog.h index 97b6da07..deed66fd 100644 --- a/src/lib_gui/qt/window/QtIndexingDialog.h +++ b/src/lib_gui/qt/window/QtIndexingDialog.h @@ -48,6 +48,7 @@ public: void setupUnknownProgress(bool hideable); void setupProgress(bool hideable); + void updateTitle(const QString& title); void updateMessage(const QString& message); std::wstring getMessage() const; void updateProgress(size_t progress); diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp index 8e660240..26f59b24 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.cpp @@ -11,6 +11,7 @@ #include "QtProjectWizzardContentCppStandard.h" #include "QtProjectWizzardContentCrossCompilationOptions.h" #include "QtProjectWizzardContentCStandard.h" +#include "QtProjectWizzardContentCustomCommand.h" #include "QtProjectWizzardContentExtensions.h" #include "QtProjectWizzardContentFlags.h" #include "QtProjectWizzardContentJavaStandard.h" @@ -25,6 +26,7 @@ #include "QtSourceGroupWizzardPage.h" #include "SourceGroupSettingsCEmpty.h" #include "SourceGroupSettingsCppEmpty.h" +#include "SourceGroupSettingsCustomCommand.h" #include "SourceGroupSettingsCxxCdb.h" #include "SourceGroupSettingsCxxCdbVs.h" #include "SourceGroupSettingsCxxCodeblocks.h" @@ -116,7 +118,7 @@ namespace { QtSourceGroupWizzardPage page("Framework Search Paths"); page.addContentCreatorWithSettings(WIZZARD_CONTENT_CONTEXT_ALL); - page.addContentCreatorSimple(WIZZARD_CONTENT_CONTEXT_ALL); + page.addContentCreatorSimple(WIZZARD_CONTENT_CONTEXT_ALL); pages.push_back(page); } { @@ -148,7 +150,7 @@ namespace { QtSourceGroupWizzardPage page("Include Paths"); page.addContentCreatorWithSettings(WIZZARD_CONTENT_CONTEXT_ALL); - page.addContentCreatorSimple(WIZZARD_CONTENT_CONTEXT_ALL); + page.addContentCreatorSimple(WIZZARD_CONTENT_CONTEXT_ALL); pages.push_back(page); } if (utility::getOsType() == OS_MAC) @@ -402,6 +404,21 @@ namespace return pages; } + template<> + std::vector> getSourceGroupWizzardPages() + { + std::vector> pages; + { + QtSourceGroupWizzardPage page("Indexed Paths"); + page.addContentCreatorWithSettings(WIZZARD_CONTENT_CONTEXT_ALL); + page.addContentCreatorWithSettings(WIZZARD_CONTENT_CONTEXT_ALL); + page.addContentCreatorWithSettings(WIZZARD_CONTENT_CONTEXT_ALL); + page.addContentCreatorWithSettings(WIZZARD_CONTENT_CONTEXT_ALL); + pages.push_back(page); + } + return pages; + } + template void fillSummary(QtProjectWizzardContentGroup* summary, std::shared_ptr settings, QtProjectWizzardWindow* window) { @@ -476,7 +493,7 @@ void QtProjectWizzard::newProjectFromCDB(const FilePath& filePath) std::make_shared(utility::getUuidString(), m_projectSettings.get()); sourceGroupSettings->setCompilationDatabasePath(filePath); - executeSoureGroupSetup(sourceGroupSettings); + executeSourceGroupSetup(sourceGroupSettings); } void QtProjectWizzard::editProject(const FilePath& settingsPath) @@ -633,7 +650,7 @@ void QtProjectWizzard::handlePrevious() } template -void QtProjectWizzard::executeSoureGroupSetup(std::shared_ptr settings) +void QtProjectWizzard::executeSourceGroupSetup(std::shared_ptr settings) { std::shared_ptr> wizzard = std::make_shared>( settings, @@ -825,6 +842,10 @@ void QtProjectWizzard::selectedSourceGroupChanged(int index) { fillSummary(summary, settings, this); } + else if (std::shared_ptr settings = std::dynamic_pointer_cast(group)) + { + fillSummary(summary, settings, this); + } setContent(summary); @@ -1003,46 +1024,46 @@ void QtProjectWizzard::selectedProjectType(SourceGroupType sourceGroupType) { std::shared_ptr settings = std::make_shared(sourceGroupId, m_projectSettings.get()); addMsvcCompatibilityFlagsOnDemand(settings); - executeSoureGroupSetup(settings); + executeSourceGroupSetup(settings); } break; case SOURCE_GROUP_CPP_EMPTY: { std::shared_ptr settings = std::make_shared(sourceGroupId, m_projectSettings.get()); addMsvcCompatibilityFlagsOnDemand(settings); - executeSoureGroupSetup(settings); + executeSourceGroupSetup(settings); } break; case SOURCE_GROUP_CXX_CDB: { std::shared_ptr settings = std::make_shared(sourceGroupId, m_projectSettings.get()); - executeSoureGroupSetup(settings); + executeSourceGroupSetup(settings); } break; case SOURCE_GROUP_CXX_CODEBLOCKS: { std::shared_ptr settings = std::make_shared(sourceGroupId, m_projectSettings.get()); addMsvcCompatibilityFlagsOnDemand(settings); - executeSoureGroupSetup(settings); + executeSourceGroupSetup(settings); } break; case SOURCE_GROUP_CXX_SONARGRAPH: { std::shared_ptr settings = std::make_shared(sourceGroupId, m_projectSettings.get()); addMsvcCompatibilityFlagsOnDemand(settings); - executeSoureGroupSetup(settings); + executeSourceGroupSetup(settings); } break; case SOURCE_GROUP_CXX_VS: { std::shared_ptr settings = std::make_shared(sourceGroupId, m_projectSettings.get()); - executeSoureGroupSetup(settings); + executeSourceGroupSetup(settings); } break; case SOURCE_GROUP_JAVA_EMPTY: { std::shared_ptr settings = std::make_shared(sourceGroupId, m_projectSettings.get()); - executeSoureGroupSetup(settings); + executeSourceGroupSetup(settings); } break; case SOURCE_GROUP_JAVA_MAVEN: @@ -1056,7 +1077,7 @@ void QtProjectWizzard::selectedProjectType(SourceGroupType sourceGroupType) L"/maven" ) ); - executeSoureGroupSetup(settings); + executeSourceGroupSetup(settings); } break; case SOURCE_GROUP_JAVA_GRADLE: @@ -1070,13 +1091,19 @@ void QtProjectWizzard::selectedProjectType(SourceGroupType sourceGroupType) L"/gradle" ) ); - executeSoureGroupSetup(settings); + executeSourceGroupSetup(settings); } break; - case SOURCE_GROUP_JAVA_SONARGRAPH: + case SOURCE_GROUP_JAVA_SONARGRAPH: { std::shared_ptr settings = std::make_shared(sourceGroupId, m_projectSettings.get()); - executeSoureGroupSetup(settings); + executeSourceGroupSetup(settings); + } + break; + case SOURCE_GROUP_CUSTOM_COMMAND: + { + std::shared_ptr settings = std::make_shared(sourceGroupId, m_projectSettings.get()); + executeSourceGroupSetup(settings); } break; case SOURCE_GROUP_UNKNOWN: diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h index e5674f08..d6d1062e 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzard.h @@ -42,7 +42,7 @@ protected: private: template - void executeSoureGroupSetup(std::shared_ptr settings); + void executeSourceGroupSetup(std::shared_ptr settings); QtProjectWizzardWindow* createWindowWithContent( std::function func); diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCustomCommand.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCustomCommand.cpp new file mode 100644 index 00000000..9a8aeebe --- /dev/null +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCustomCommand.cpp @@ -0,0 +1,92 @@ +#include "QtProjectWizzardContentCustomCommand.h" + +#include +#include +#include + +#include "FileSystem.h" +#include "ProjectSettings.h" +#include "SourceGroupSettingsCustomCommand.h" +#include "SqliteIndexStorage.h" + +QtProjectWizzardContentCustomCommand::QtProjectWizzardContentCustomCommand( + std::shared_ptr settings, + QtProjectWizzardWindow* window +) + : QtProjectWizzardContent(window) + , m_settings(settings) + , m_customCommand(nullptr) +{ +} + +void QtProjectWizzardContentCustomCommand::populate(QGridLayout* layout, int& row) +{ + if (!isInForm()) + { + layout->setRowMinimumHeight(row, 15); + row++; + } + + QLabel* nameLabel = createFormLabel("Custom Command"); + addHelpButton( + "Custom Command", + "

Specify the commandline call that will be executed for each source file in this Source Group. " + "You can use the following variables, $SOURCE_PATH is mandatory.

" + "
    " + "
  • $SOURCE_PATH - Path to each source file (mandatory)
  • " + "
  • $PROJECT_PATH - Path to project file: \"" + + QString::fromStdWString(m_settings->getProjectSettings()->getProjectFilePath().wstr()) + "\"
  • " + "
  • $DB_PATH - Path to database file: \"" + + QString::fromStdWString(m_settings->getProjectSettings()->getTempDBFilePath().wstr()) + "\"
  • " + "
  • $STORAGE_VERSION - Storage version used by this Sourcetrail version: \"" + + QString::number(SqliteIndexStorage::getStorageVersion()) + "\"
  • " + "
", + layout, row + ); + + m_customCommand = new QLineEdit(); + m_customCommand->setObjectName("name"); + m_customCommand->setAttribute(Qt::WA_MacShowFocusRect, 0); + + layout->addWidget(nameLabel, row, QtProjectWizzardWindow::FRONT_COL, Qt::AlignRight); + layout->addWidget(m_customCommand, row, QtProjectWizzardWindow::BACK_COL); + layout->setRowMinimumHeight(row, 30); + row++; + + if (!isInForm()) + { + layout->setRowMinimumHeight(row, 15); + layout->setRowStretch(row, 1); + } +} + +void QtProjectWizzardContentCustomCommand::load() +{ + m_customCommand->setText(QString::fromStdWString(m_settings->getCustomCommand())); +} + +void QtProjectWizzardContentCustomCommand::save() +{ + m_settings->setCustomCommand(m_customCommand->text().toStdWString()); +} + +bool QtProjectWizzardContentCustomCommand::check() +{ + if (m_customCommand->text().isEmpty()) + { + QMessageBox msgBox; + msgBox.setText("Please enter a custom command."); + msgBox.exec(); + return false; + } + + if (m_customCommand->text().toStdWString().find(L"$SOURCE_PATH") == std::wstring::npos) + { + QMessageBox msgBox; + msgBox.setText("The variable $SOURCE_PATH is missing in the custom command."); + msgBox.exec(); + return false; + } + + return true; +} diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCustomCommand.h b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCustomCommand.h new file mode 100644 index 00000000..8be03e90 --- /dev/null +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentCustomCommand.h @@ -0,0 +1,32 @@ +#ifndef QT_PROJECT_WIZZARD_CONTENT_CUSTOM_COMMAND_H +#define QT_PROJECT_WIZZARD_CONTENT_CUSTOM_COMMAND_H + +#include "QtProjectWizzardContent.h" + +class QLineEdit; +class SourceGroupSettingsCustomCommand; + +class QtProjectWizzardContentCustomCommand + : public QtProjectWizzardContent +{ + Q_OBJECT + +public: + QtProjectWizzardContentCustomCommand( + std::shared_ptr settings, + QtProjectWizzardWindow* window); + + // QtProjectWizzardContent implementation + virtual void populate(QGridLayout* layout, int& row) override; + + virtual void load() override; + virtual void save() override; + virtual bool check() override; + +private: + std::shared_ptr m_settings; + + QLineEdit* m_customCommand; +}; + +#endif // QT_PROJECT_WIZZARD_CONTENT_CUSTOM_COMMAND_H diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp index 08743c07..41c295b7 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentPaths.cpp @@ -8,12 +8,14 @@ #include "DialogView.h" #include "IndexerCommandCxx.h" -#include "SourceGroupCxxEmpty.h" -#include "SourceGroupJavaEmpty.h" #include "QtDialogView.h" #include "QtPathListDialog.h" #include "QtSelectPathsDialog.h" +#include "SourceGroupCustomCommand.h" +#include "SourceGroupCxxEmpty.h" +#include "SourceGroupJavaEmpty.h" #include "ApplicationSettings.h" +#include "SourceGroupSettingsCustomCommand.h" #include "SourceGroupSettingsCxx.h" #include "SourceGroupSettingsCxxCdb.h" #include "SourceGroupSettingsCxxCodeblocks.h" @@ -252,6 +254,10 @@ std::vector QtProjectWizzardContentPathsSource::getFilePaths() const { allSourceFilePaths = SourceGroupJavaEmpty(settings).getAllSourceFilePaths(); } + else if (std::shared_ptr settings = std::dynamic_pointer_cast(m_settings)) + { + allSourceFilePaths = SourceGroupCustomCommand(settings).getAllSourceFilePaths(); + } return utility::getAsRelativeIfShorter( utility::toVector(allSourceFilePaths), diff --git a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSelect.cpp b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSelect.cpp index 3c6515bc..142f4e2d 100644 --- a/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSelect.cpp +++ b/src/lib_gui/qt/window/project_wizzard/QtProjectWizzardContentSelect.cpp @@ -42,6 +42,7 @@ void QtProjectWizzardContentSelect::populate(QGridLayout* layout, int& row) sourceGroupInfos[LANGUAGE_JAVA].push_back(SourceGroupInfo(SOURCE_GROUP_JAVA_MAVEN)); sourceGroupInfos[LANGUAGE_JAVA].push_back(SourceGroupInfo(SOURCE_GROUP_JAVA_GRADLE)); sourceGroupInfos[LANGUAGE_JAVA].push_back(SourceGroupInfo(SOURCE_GROUP_JAVA_SONARGRAPH)); + sourceGroupInfos[LANGUAGE_CUSTOM].push_back(SourceGroupInfo(SOURCE_GROUP_CUSTOM_COMMAND)); // define which icons should be used for which kind of source group m_sourceGroupTypeIconName[SOURCE_GROUP_C_EMPTY] = L"empty_icon"; @@ -54,6 +55,7 @@ void QtProjectWizzardContentSelect::populate(QGridLayout* layout, int& row) m_sourceGroupTypeIconName[SOURCE_GROUP_JAVA_MAVEN] = L"mvn_icon"; m_sourceGroupTypeIconName[SOURCE_GROUP_JAVA_GRADLE] = L"gradle_icon"; m_sourceGroupTypeIconName[SOURCE_GROUP_JAVA_SONARGRAPH] = L"sonargraph_icon"; + m_sourceGroupTypeIconName[SOURCE_GROUP_CUSTOM_COMMAND] = L"empty_icon"; // define descriptions for each kind of Source Group m_sourceGroupTypeDescriptions[SOURCE_GROUP_C_EMPTY] = "Create a new Sourcetrail Source Group by defining which C files will be indexed."; @@ -78,9 +80,12 @@ void QtProjectWizzardContentSelect::populate(QGridLayout* layout, int& row) m_sourceGroupTypeDescriptions[SOURCE_GROUP_JAVA_GRADLE] = "Create a new Source Group from an existing Gradle project."; m_sourceGroupTypeDescriptions[SOURCE_GROUP_JAVA_SONARGRAPH] = "Create a new Source Group from an existing Sonargraph project file."; + m_sourceGroupTypeDescriptions[SOURCE_GROUP_CUSTOM_COMMAND] = "Create a new Source Group executing a custom command on each source file. " + "This Source Group type can be used on SourcetrailDB binaries that add " + "custom language support"; QVBoxLayout* vlayout = new QVBoxLayout(); - vlayout->setContentsMargins(0, 30, 0, 0); + vlayout->setContentsMargins(0, 10, 0, 0); vlayout->setSpacing(10); m_languages = new QButtonGroup(); diff --git a/src/lib_gui/utility/utilityApp.cpp b/src/lib_gui/utility/utilityApp.cpp index f2c477c3..d33ef77c 100644 --- a/src/lib_gui/utility/utilityApp.cpp +++ b/src/lib_gui/utility/utilityApp.cpp @@ -96,7 +96,8 @@ int utility::executeProcessAndGetExitCode( const std::wstring& commandPath, const std::vector& commandArguments, const FilePath& workingDirectory, - const int timeout + const int timeout, + std::wstring* processOutput ){ QProcess process; @@ -124,7 +125,14 @@ int utility::executeProcessAndGetExitCode( } int exitCode = process.exitCode(); + + if (processOutput != nullptr) + { + *processOutput = utility::trim(QString(process.readAll()).toStdWString()); + } + process.close(); + return exitCode; } diff --git a/src/lib_gui/utility/utilityApp.h b/src/lib_gui/utility/utilityApp.h index 9a33c03c..864372b2 100644 --- a/src/lib_gui/utility/utilityApp.h +++ b/src/lib_gui/utility/utilityApp.h @@ -18,7 +18,8 @@ namespace utility const std::wstring& commandPath, const std::vector& commandArguments, const FilePath& workingDirectory = FilePath(), - const int timeout = 30000 + const int timeout = 30000, + std::wstring* processOutput = nullptr ); void killRunningProcesses(); diff --git a/src/test/SourceGroupTestSuite.h b/src/test/SourceGroupTestSuite.h index f2ea14d0..cdb69ba8 100644 --- a/src/test/SourceGroupTestSuite.h +++ b/src/test/SourceGroupTestSuite.h @@ -2,6 +2,7 @@ #include +#include "IndexerCommandCustom.h" #include "IndexerCommandCxx.h" #include "IndexerCommandJava.h" #include "JavaEnvironmentFactory.h" @@ -9,6 +10,7 @@ #include "SourceGroupCxxCdb.h" #include "SourceGroupCxxCodeblocks.h" #include "SourceGroupCxxSonargraph.h" +#include "SourceGroupCustomCommand.h" #include "SourceGroupJavaEmpty.h" #include "SourceGroupJavaGradle.h" #include "SourceGroupJavaMaven.h" @@ -18,6 +20,7 @@ #include "SourceGroupSettingsCxxCdb.h" #include "SourceGroupSettingsCxxCodeblocks.h" #include "SourceGroupSettingsCxxSonargraph.h" +#include "SourceGroupSettingsCustomCommand.h" #include "SourceGroupSettingsJavaEmpty.h" #include "SourceGroupSettingsJavaGradle.h" #include "SourceGroupSettingsJavaMaven.h" @@ -389,6 +392,22 @@ public: applicationSettings->setJreSystemLibraryPaths(storedJreSystemLibraryPaths); } + void test_source_group_custom_command_generates_expected_output() + { + const std::wstring projectName = L"custom_command"; + + ProjectSettings projectSettings; + projectSettings.setProjectFilePath(L"non_existent_project", getInputDirectoryPath(projectName)); + + std::shared_ptr sourceGroupSettings = std::make_shared("fake_id", &projectSettings); + sourceGroupSettings->setCustomCommand(L"echo \"Hello World\""); + sourceGroupSettings->setSourcePaths({ getInputDirectoryPath(projectName).concatenate(L"/src") }); + sourceGroupSettings->setSourceExtensions({ L".txt" }); + sourceGroupSettings->setExcludeFilterStrings({ L"**/excluded/**" }); + + generateAndCompareExpectedOutput(projectName, std::make_shared(sourceGroupSettings)); + } + // Special Tests void test_sourcegroup_java_sonargraph_with_cpp_modules_does_not_generate_output() @@ -546,6 +565,10 @@ private: { return indexerCommandJavaToString(indexerCommandJava, baseDirectory); } + if (std::shared_ptr indexerCommandCustom = std::dynamic_pointer_cast(indexerCommand)) + { + return indexerCommandCustomToString(indexerCommandCustom, baseDirectory); + } return L"Unsupported indexer command type: " + utility::decodeFromUtf8(indexerCommandTypeToString(indexerCommand->getIndexerCommandType())); } return L"No IndexerCommand provided."; @@ -586,4 +609,12 @@ private: } return result; } + + std::wstring indexerCommandCustomToString(std::shared_ptr indexerCommand, const FilePath& baseDirectory) + { + std::wstring result; + result += L"SourceFilePath: \"" + indexerCommand->getSourceFilePath().getRelativeTo(baseDirectory).wstr() + L"\"\n"; + result += L"\tCustom Command: \"" + indexerCommand->getCustomCommand() + L"\"\n"; + return result; + } }; diff --git a/testing/project_setup/custom_command/1_setup.sh b/testing/project_setup/custom_command/1_setup.sh new file mode 100755 index 00000000..7e4992e7 --- /dev/null +++ b/testing/project_setup/custom_command/1_setup.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# get absolute path to parent directory of script +MY_PATH=`dirname "$0"` +if [[ "${MY_PATH}" != *\\* ]] +then + cd $MY_PATH + MY_PATH=`pwd` +fi +MY_PATH="${MY_PATH//\\//}" + +SRC_PATH=$MY_PATH/data +WORKING_COPY_PATH=$MY_PATH/working_copy + +mkdir -p $WORKING_COPY_PATH + +cp -a $SRC_PATH/. $WORKING_COPY_PATH + +echo "Setup Complete" diff --git a/testing/project_setup/custom_command/2_teardown.sh b/testing/project_setup/custom_command/2_teardown.sh new file mode 100755 index 00000000..0877a78a --- /dev/null +++ b/testing/project_setup/custom_command/2_teardown.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# get absolute path to parent directory of script +MY_PATH=`dirname "$0"` +if [[ "${MY_PATH}" != *\\* ]] +then + cd $MY_PATH + MY_PATH=`pwd` +fi +MY_PATH="${MY_PATH//\\//}" + +WORKING_COPY_PATH=$MY_PATH/working_copy + +rm -rf $WORKING_COPY_PATH + +echo "Teardown Complete" diff --git a/testing/project_setup/custom_command/checklist.txt b/testing/project_setup/custom_command/checklist.txt new file mode 100644 index 00000000..89dae7ee --- /dev/null +++ b/testing/project_setup/custom_command/checklist.txt @@ -0,0 +1,38 @@ +* Run "1_setup.sh" +* Start up Sourcetrail +* Click "New Project" +* Enter a project name +* Set "./working_copy" as project location +* Click "Add Source Group" +* Select "Custom" -> "Custom Command Source Group" +* Click "Next" +* Click "Next" +* Add "python add.py $PROJECT_PATH $DB_PATH $STORAGE_VERSION $SOURCE_PATH" to "Custom Command" +* Add "./src" to "Files & Directories to Index" +* Add "**excl.txt" to "Excluded Files & Directories" +* Add ".txt" to "Source File Extensions" +* Click "Next" +* Click "Create" +* Validate "All files" is the only option selectable +* Validate "source files to index" shows "3" +* Click "Start" +* Validate Project indexed without error +* Click "OK" +* Validate "out.txt" contains 3 lines: + /a.txt + /b.txt + /c.txt +* Press "Refresh" button +* Validate "Updated files" is selected +* Validate "source files to index" shows "3" again +* Click "Cancel" +* Click "Edit Project" +* Change "Custom Command" to "pyt add.py" +* Click "Next" +* Validate "Warning appears that $SOURCE_PATH is not defined in command" +* Change "Custom Command" to "pyt add.py $SOURCE_PATH" +* Click "Refresh" button +* Click "Start" +* Validate "Log View appears showing errors that command execution failed". +* Close Sourcetrail +* Run "2_teardown.sh" diff --git a/testing/project_setup/custom_command/data/add.py b/testing/project_setup/custom_command/data/add.py new file mode 100644 index 00000000..7ba77c86 --- /dev/null +++ b/testing/project_setup/custom_command/data/add.py @@ -0,0 +1,6 @@ +import sys +# import time +# time.sleep(1) + +with open("out.txt", "a") as myfile: + myfile.write(sys.argv[1] + ' ' + sys.argv[2] + ' ' + sys.argv[3] + ' ' + sys.argv[4] + '\n') diff --git a/testing/project_setup/custom_command/data/src/a.txt b/testing/project_setup/custom_command/data/src/a.txt new file mode 100644 index 00000000..e69de29b diff --git a/testing/project_setup/custom_command/data/src/b.txt b/testing/project_setup/custom_command/data/src/b.txt new file mode 100644 index 00000000..e69de29b diff --git a/testing/project_setup/custom_command/data/src/c.txt b/testing/project_setup/custom_command/data/src/c.txt new file mode 100644 index 00000000..e69de29b diff --git a/testing/project_setup/custom_command/data/src/d.c b/testing/project_setup/custom_command/data/src/d.c new file mode 100644 index 00000000..e69de29b diff --git a/testing/project_setup/custom_command/data/src/excl.txt b/testing/project_setup/custom_command/data/src/excl.txt new file mode 100644 index 00000000..e69de29b