File indexing completed on 2024-12-08 13:30:51
0001 // clang-format off 0002 /** 0003 * KDiff3 - Text Diff And Merge Tool 0004 * 0005 * SPDX-FileCopyrightText: 2021 David Hallas <david@davidhallas.dk> 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 * 0008 */ 0009 // clang-format on 0010 0011 #include "GitIgnoreList.h" 0012 0013 #include "Logging.h" 0014 #include "fileaccess.h" 0015 0016 #include <algorithm> 0017 #include <utility> 0018 0019 #include <QFile> 0020 #include <QStringList> 0021 #include <QTextStream> 0022 0023 namespace { 0024 0025 bool isComment(const QString& line) 0026 { 0027 return line.startsWith(QChar('#')); 0028 } 0029 0030 } // namespace 0031 0032 GitIgnoreList::GitIgnoreList() = default; 0033 0034 GitIgnoreList::~GitIgnoreList() = default; 0035 0036 void GitIgnoreList::enterDir(const QString& dir, const DirectoryList& directoryList) 0037 { 0038 const auto directoryListIt = std::find_if(directoryList.begin(), directoryList.end(), [](const FileAccess& file) { 0039 return file.fileName() == ".gitignore"; 0040 }); 0041 if(directoryListIt != directoryList.end()) 0042 { 0043 addEntries(dir, readFile(directoryListIt->absoluteFilePath())); 0044 } 0045 } 0046 0047 bool GitIgnoreList::matches(const QString& dir, const QString& text, bool bCaseSensitive) const 0048 { 0049 for(auto& dirPattern: m_patterns) 0050 { 0051 if(!dir.startsWith(dirPattern.first)) 0052 { 0053 continue; 0054 } 0055 for(QRegularExpression& pattern: dirPattern.second) 0056 { 0057 if(!bCaseSensitive) 0058 { 0059 pattern.setPatternOptions(QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption); 0060 } 0061 else 0062 { 0063 pattern.setPatternOptions(QRegularExpression::UseUnicodePropertiesOption); 0064 } 0065 const QRegularExpressionMatch match = pattern.match(text); 0066 if(match.hasMatch()) 0067 { 0068 qCDebug(kdiffGitIgnoreList) << "Matched entry" << text; 0069 return true; 0070 } 0071 } 0072 } 0073 return false; 0074 } 0075 0076 QString GitIgnoreList::readFile(const QString& fileName) const 0077 { 0078 QFile file(fileName); 0079 if(!file.open(QIODevice::ReadOnly)) 0080 { 0081 return QString(); 0082 } 0083 QTextStream stream(&file); 0084 return stream.readAll(); 0085 } 0086 0087 void GitIgnoreList::addEntries(const QString& dir, const QString& lines) 0088 { 0089 static const QRegularExpression newLineReg = QRegularExpression("[\r\n]"); 0090 const QStringList lineList = lines.split(newLineReg, Qt::SkipEmptyParts); 0091 for(const QString& line: lineList) 0092 { 0093 if(isComment(line)) 0094 { 0095 continue; 0096 } 0097 QRegularExpression expression(QRegularExpression::wildcardToRegularExpression(line)); 0098 if(!expression.isValid()) 0099 { 0100 qCDebug(kdiffGitIgnoreList) << "Expression" << line << "is not valid - skipping ..."; 0101 continue; 0102 } 0103 qCDebug(kdiffGitIgnoreList) << "Adding entry [" << dir << "]" << line; 0104 m_patterns[dir].push_back(expression); 0105 } 0106 }