/**************************************************************************** ** ** Copyright (C) 2019 The Qt Company ** Contact: https://www.qt.io/licensing/ ** ** This file is part of UsageStatistic plugin for Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ #include "kitsource.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "common/scopedsettingsgroupsetter.h" namespace UsageStatistic { namespace Internal { using namespace KUserFeedback; using namespace ProjectExplorer; KitSource::KitSource() : AbstractDataSource(QStringLiteral("kits"), Provider::DetailedUsageStatistics) { QObject::connect(ProjectExplorer::BuildManager::instance(), &ProjectExplorer::BuildManager::buildQueueFinished, [&](bool success) { const Project *project = ProjectManager::startupProject(); const Target *target = project ? project->activeTarget() : nullptr; const Kit *kit = target ? target->kit() : nullptr; const Toolchain *toolchain = ToolchainKitAspect::toolchain( kit, Constants::CXX_LANGUAGE_ID); const Abi abi = toolchain ? toolchain->targetAbi() : Abi(); const QString abiName = abi.toString(); QVariantMap &bucket = success ? m_buildSuccessesForToolchain : m_buildFailsForToolchain; bucket[abiName] = bucket.value(abiName, 0).toInt() + 1; }); } KitSource::~KitSource() = default; QString KitSource::name() const { return tr("Kits"); } QString KitSource::description() const { return tr("Kits usage statistics: compilers, debuggers, target architecture, and so on."); } static QString kitsInfoKey() { return QStringLiteral("kitsInfo"); } static QString buildSuccessesKey() { return QStringLiteral("buildSuccesses"); } static QString buildFailsKey() { return QStringLiteral("buildFails"); } static QString extractToolchainVersion(const Toolchain &toolchain) { try { return dynamic_cast(toolchain).version(); } catch (...) { return {}; } } void KitSource::loadImpl(QSettings *settings) { auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings); m_buildSuccessesForToolchain = settings->value(buildSuccessesKey(), QVariantMap{}).toMap(); m_buildFailsForToolchain = settings->value(buildFailsKey(), QVariantMap{}).toMap(); } void KitSource::storeImpl(QSettings *settings) { auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings); settings->setValue(buildSuccessesKey(), m_buildSuccessesForToolchain); settings->setValue(buildFailsKey(), m_buildFailsForToolchain); } void KitSource::resetImpl(QSettings *settings) { m_buildSuccessesForToolchain.clear(); m_buildFailsForToolchain.clear(); storeImpl(settings); } class KitInfo { public: KitInfo(Kit &kit, const KitSource &source) : m_kit(kit), m_source(source) { addKitInfo(); } KitInfo &withQtVersionInfo() { static const QString qtKey = QStringLiteral("qt"); static const QString qtQmlDebuggingSupportKey = QStringLiteral("qmlDebugging"); static const QString qtQmlCompilerSupportKey = QStringLiteral("qmlCompiler"); static const QString qtAbisKey = QStringLiteral("abis"); if (auto qtVersion = QtSupport::QtKitAspect::qtVersion(&m_kit)) { QVariantMap qtData; qtData.insert(versionKey(), qtVersion->qtVersionString()); qtData.insert(qtQmlDebuggingSupportKey, qtVersion->isQmlDebuggingSupported()); qtData.insert(qtQmlCompilerSupportKey, qtVersion->isQtQuickCompilerSupported()); qtData.insert(qtAbisKey, abisToVarinatList(qtVersion->qtAbis())); m_map.insert(qtKey, qtData); } return *this; } KitInfo &withCompilerInfo() { static const QString compilerKey = QStringLiteral("compiler"); if (auto toolchain = ToolchainKitAspect::toolchain(&m_kit, Constants::CXX_LANGUAGE_ID)) { const QString abiName = toolchain->targetAbi().toString(); m_map.insert(compilerKey, QVariantMap{{nameKey(), toolchain->typeDisplayName()}, {abiKey(), abiName}, {versionKey(), extractToolchainVersion(*toolchain)}, {buildSuccessesKey(), m_source.m_buildSuccessesForToolchain.value(abiName).toInt()}, {buildFailsKey(), m_source.m_buildFailsForToolchain.value(abiName).toInt()}}); } return *this; } KitInfo &withDebuggerInfo() { static const QString debuggerKey = QStringLiteral("debugger"); if (auto debuggerInfo = Debugger::DebuggerKitAspect::debugger(&m_kit)) { m_map.insert(debuggerKey, QVariantMap{{nameKey(), debuggerInfo->engineTypeName()}, {versionKey(), debuggerInfo->version()}}); } return *this; } QVariantMap extract() const { return m_map; } private: // Methods void addKitInfo() { static QString defaultKitKey = QStringLiteral("default"); m_map.insert(defaultKitKey, &m_kit == KitManager::defaultKit()); } static QVariantMap abiToVariantMap(const Abi &abi) { static const QString archKey = QStringLiteral("arch"); static const QString osKey = QStringLiteral("os"); static const QString osFlavorKey = QStringLiteral("osFlavor"); static const QString binaryFormatKey = QStringLiteral("binaryFormat"); static const QString wordWidthKey = QStringLiteral("wordWidth"); return QVariantMap{{archKey , Abi::toString(abi.architecture())}, {osKey , Abi::toString(abi.os()) }, {osFlavorKey , Abi::toString(abi.osFlavor()) }, {binaryFormatKey, Abi::toString(abi.binaryFormat())}, {wordWidthKey , Abi::toString(abi.wordWidth()) }}; } template QVariantList abisToVarinatList(const Container &abis) { QVariantList result; for (auto &&abi : abis) { result << abiToVariantMap(abi); } return result; } static QString versionKey() { return QStringLiteral("version"); } static QString nameKey() { return QStringLiteral("name"); } static QString abiKey() { return QStringLiteral("abi"); } private: // Data Kit &m_kit; const KitSource &m_source; QVariantMap m_map; }; QVariant KitSource::data() { QVariantList kitsInfoList; for (auto &&kit : KitManager::instance()->kits()) { if (kit && kit->isValid()) { kitsInfoList << KitInfo(*kit, *this) .withCompilerInfo() .withDebuggerInfo() .withQtVersionInfo() .extract(); } } return QVariantMap{{kitsInfoKey(), kitsInfoList}}; } } // namespace Internal } // namespace UsageStatistic