File indexing completed on 2024-04-21 12:11:06

0001 /* This file is part of KDevelop
0002 
0003    Copyright 2016 Anton Anikin <anton.anikin@htower.ru>
0004 
0005    This program is free software; you can redistribute it and/or
0006    modify it under the terms of the GNU General Public
0007    License as published by the Free Software Foundation; either
0008    version 2 of the License, or (at your option) any later version.
0009 
0010    This program is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0013    General Public License for more details.
0014 
0015    You should have received a copy of the GNU General Public License
0016    along with this program; see the file COPYING.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018    Boston, MA 02110-1301, USA.
0019 */
0020 
0021 #include "parameters.h"
0022 
0023 #include "globalsettings.h"
0024 #include "projectsettings.h"
0025 #include "rules.h"
0026 #include "utils.h"
0027 
0028 #include <KShell>
0029 #include <klocalizedstring.h>
0030 #include <interfaces/iproject.h>
0031 #include <serialization/indexedstring.h>
0032 #include <project/interfaces/ibuildsystemmanager.h>
0033 #include <project/projectmodel.h>
0034 
0035 #include <QDir>
0036 #include <QFileInfo>
0037 #include <QStandardPaths>
0038 #include <QTextStream>
0039 #include <QMessageBox>
0040 
0041 namespace verapp
0042 {
0043 
0044 namespace defaults
0045 {
0046 
0047 QString executablePath()
0048 {
0049     QString path = QStandardPaths::findExecutable(QStringLiteral("vera++"));
0050     return path.isEmpty() ? QStringLiteral("vera++") : path;
0051 }
0052 
0053 bool hideOutputView()
0054 {
0055     return true;
0056 }
0057 
0058 }
0059 
0060 Parameters::Parameters(KDevelop::IProject* project)
0061     : m_project(project)
0062 {
0063     executablePath = KDevelop::Path(GlobalSettings::executablePath()).toLocalFile();
0064     hideOutputView = GlobalSettings::hideOutputView();
0065 
0066     if (!project) {
0067         for (int intType = rules::Type::FIRST; intType <= rules::Type::LAST; ++intType) {
0068             rules::Type ruleType = static_cast<rules::Type>(intType);
0069 
0070             m_ruleEnabled[ruleType] = defaults::isRuleEnabled(ruleType);
0071         }
0072 
0073         return;
0074     }
0075 
0076     ProjectSettings projectSettings;
0077     projectSettings.setSharedConfig(project->projectConfiguration());
0078     projectSettings.load();
0079 
0080     for (int intType = rules::Type::FIRST; intType <= rules::Type::LAST; ++intType) {
0081         rules::Type ruleType = static_cast<rules::Type>(intType);
0082 
0083         m_ruleEnabled[ruleType] = projectSettings.rule(intType);
0084     }
0085 
0086     extraParameters = projectSettings.extraParameters();
0087 
0088     m_projectRootPath  = m_project->path();
0089     m_projectBuildPath = m_project->buildSystemManager()->buildDirectory(m_project->projectItem());
0090 }
0091 
0092 QStringList Parameters::commandLine() const
0093 {
0094     QStringList arguments;
0095 
0096     arguments << executablePath;
0097 
0098     arguments << QStringLiteral("--show-rule");
0099     arguments << QStringLiteral("--no-duplicate");
0100 
0101     for (int intType = rules::Type::FIRST; intType <= rules::Type::LAST; ++intType) {
0102         rules::Type ruleType = static_cast<rules::Type>(intType);
0103 
0104         if (m_ruleEnabled[ruleType]) {
0105             arguments << "-R";
0106             arguments << rules::name(ruleType);
0107         }
0108     }
0109 
0110     if (!extraParameters.isEmpty()) {
0111         arguments << KShell::splitArgs(applyPlaceholders(extraParameters));
0112     }
0113 
0114     return arguments;
0115 }
0116 
0117 QString Parameters::buildRunScript() const
0118 {
0119     QSet<KDevelop::IndexedString> projectFiles;
0120     QString scriptPath;
0121 
0122     if (!checkPath.isEmpty() && QFileInfo(checkPath).isFile()) {
0123         projectFiles.insert(KDevelop::IndexedString(checkPath));
0124     } else if (m_project) {
0125         projectFiles = m_project->fileSet();
0126 
0127         QMutableSetIterator<KDevelop::IndexedString> i(projectFiles);
0128         while (i.hasNext()) {
0129             QString projectFile = i.next().str();
0130 
0131             if (!projectFile.startsWith(checkPath)) {
0132                 i.remove();
0133                 continue;
0134             }
0135 
0136             if (!isSupportedFile(projectFile)) {
0137                 i.remove();
0138             }
0139         }
0140     }
0141 
0142     QString tempDir = QStandardPaths::standardLocations(QStandardPaths::TempLocation).first();
0143     scriptPath = tempDir + "/kdevverapp";
0144 
0145     if (m_project) {
0146         scriptPath += "_" + m_project->name();
0147     }
0148 
0149 #ifdef Q_OS_WIN
0150     scriptPath += ".bat";
0151 #else
0152     scriptPath += ".sh";
0153 #endif
0154 
0155     QFile scriptFile(scriptPath);
0156     if (!scriptFile.open(QIODevice::WriteOnly)) {
0157         QMessageBox::critical(
0158             nullptr,
0159             i18n("Vera++ Error"),
0160             i18n("Unable to open file '%1' to write", scriptPath));
0161 
0162         return scriptPath;
0163     }
0164 
0165     QTextStream scriptStream(&scriptFile);
0166     QString veraCommand = commandLine().join(' ');
0167     int fileNumber = 0;
0168     int filesCount = projectFiles.size();
0169     foreach (const KDevelop::IndexedString& projectFile, projectFiles) {
0170         scriptStream << QString("echo Checking %1 ...\n").arg(projectFile.str());
0171 
0172         scriptStream << QString("%1 %2\n").arg(veraCommand).arg(projectFile.str());
0173 
0174         int progress = (++fileNumber)/(double)filesCount * 100.0;
0175         scriptStream << QString("echo %1/%2 files checked %3% done\n").arg(fileNumber).arg(filesCount).arg(progress);
0176     }
0177 
0178     scriptFile.setPermissions(
0179         QFileDevice::ReadOwner |
0180         QFileDevice::WriteOwner |
0181         QFileDevice::ExeOwner);
0182     scriptFile.close();
0183 
0184     return scriptPath;
0185 }
0186 
0187 bool Parameters::isRuleEnabled(rules::Type type) const
0188 {
0189     return m_ruleEnabled[type];
0190 }
0191 
0192 void Parameters::setRuleEnabled(rules::Type type, bool value)
0193 {
0194     m_ruleEnabled[type] = value;
0195 }
0196 
0197 QString Parameters::applyPlaceholders(const QString& text) const
0198 {
0199     QString result(text);
0200 
0201     if (m_project) {
0202         result.replace("%p", m_projectRootPath.toLocalFile());
0203         result.replace("%b", m_projectBuildPath.toLocalFile());
0204     }
0205 
0206     return result;
0207 }
0208 
0209 namespace defaults
0210 {
0211 
0212 bool isRuleEnabled(rules::Type type)
0213 {
0214     // default Vera++ profile
0215     if (type == rules::F002 || type == rules::T014) {
0216         return false;
0217     }
0218 
0219     return true;
0220 }
0221 
0222 }
0223 
0224 }