VcsManager: Use more FilePath

Change-Id: I255372c47e6d3ea55e5f8060c3c2fdd9bd155c75
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Jarek Kobus
2022-10-04 15:13:46 +02:00
parent ab7a472b94
commit 64db0009d5
4 changed files with 36 additions and 38 deletions

View File

@@ -45,7 +45,7 @@ public:
class VcsInfo { class VcsInfo {
public: public:
IVersionControl *versionControl = nullptr; IVersionControl *versionControl = nullptr;
QString topLevel; FilePath topLevel;
}; };
std::optional<VcsInfo> findInCache(const QString &dir) const std::optional<VcsInfo> findInCache(const QString &dir) const
@@ -77,18 +77,19 @@ public:
} }
} }
void cache(IVersionControl *vc, const QString &topLevel, const QString &dir) void cache(IVersionControl *vc, const FilePath &topLevel, const QString &dir)
{ {
QTC_ASSERT(QDir(dir).isAbsolute(), return); QTC_ASSERT(QDir(dir).isAbsolute(), return);
QTC_ASSERT(!dir.endsWith(QLatin1Char('/')), return); QTC_ASSERT(!dir.endsWith(QLatin1Char('/')), return);
QTC_ASSERT(QDir::fromNativeSeparators(dir) == dir, return); QTC_ASSERT(QDir::fromNativeSeparators(dir) == dir, return);
QTC_ASSERT(dir.startsWith(topLevel + QLatin1Char('/')) const QString topLevelString = topLevel.toString();
|| topLevel == dir || topLevel.isEmpty(), return); QTC_ASSERT(FilePath::fromString(dir).isChildOf(topLevel)
|| topLevelString == dir || topLevel.isEmpty(), return);
QTC_ASSERT((topLevel.isEmpty() && !vc) || (!topLevel.isEmpty() && vc), return); QTC_ASSERT((topLevel.isEmpty() && !vc) || (!topLevel.isEmpty() && vc), return);
QString tmpDir = dir; QString tmpDir = dir;
const QChar slash = QLatin1Char('/'); const QChar slash = QLatin1Char('/');
while (tmpDir.count() >= topLevel.count() && !tmpDir.isEmpty()) { while (tmpDir.count() >= topLevelString.count() && !tmpDir.isEmpty()) {
m_cachedMatches.insert(tmpDir, {vc, topLevel}); m_cachedMatches.insert(tmpDir, {vc, topLevel});
// if no vc was found, this might mean we're inside a repo internal directory (.git) // if no vc was found, this might mean we're inside a repo internal directory (.git)
// Cache only input directory, not parents // Cache only input directory, not parents
@@ -188,8 +189,8 @@ void VcsManager::resetVersionControlForDirectory(const FilePath &inputDirectory)
IVersionControl* VcsManager::findVersionControlForDirectory(const FilePath &inputDirectory, IVersionControl* VcsManager::findVersionControlForDirectory(const FilePath &inputDirectory,
FilePath *topLevelDirectory) FilePath *topLevelDirectory)
{ {
using StringVersionControlPair = QPair<QString, IVersionControl *>; using FilePathVersionControlPair = QPair<FilePath, IVersionControl *>;
using StringVersionControlPairs = QList<StringVersionControlPair>; using FilePathVersionControlPairs = QList<FilePathVersionControlPair>;
if (inputDirectory.isEmpty()) { if (inputDirectory.isEmpty()) {
if (topLevelDirectory) if (topLevelDirectory)
topLevelDirectory->clear(); topLevelDirectory->clear();
@@ -207,29 +208,29 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const FilePath &inpu
auto cachedData = d->findInCache(directory); auto cachedData = d->findInCache(directory);
if (cachedData) { if (cachedData) {
if (topLevelDirectory) if (topLevelDirectory)
*topLevelDirectory = FilePath::fromString(cachedData->topLevel); *topLevelDirectory = cachedData->topLevel;
return cachedData->versionControl; return cachedData->versionControl;
} }
// Nothing: ask the IVersionControls directly. // Nothing: ask the IVersionControls directly.
StringVersionControlPairs allThatCanManage; FilePathVersionControlPairs allThatCanManage;
const QList<IVersionControl *> versionControlList = versionControls(); const QList<IVersionControl *> versionControlList = versionControls();
for (IVersionControl *versionControl : versionControlList) { for (IVersionControl *versionControl : versionControlList) {
FilePath topLevel; FilePath topLevel;
if (versionControl->managesDirectory(FilePath::fromString(directory), &topLevel)) if (versionControl->managesDirectory(FilePath::fromString(directory), &topLevel))
allThatCanManage.push_back(StringVersionControlPair(topLevel.toString(), versionControl)); allThatCanManage.push_back({topLevel, versionControl});
} }
// To properly find a nested repository (say, git checkout inside SVN), // To properly find a nested repository (say, git checkout inside SVN),
// we need to select the version control with the longest toplevel pathname. // we need to select the version control with the longest toplevel pathname.
Utils::sort(allThatCanManage, [](const StringVersionControlPair &l, Utils::sort(allThatCanManage, [](const FilePathVersionControlPair &l,
const StringVersionControlPair &r) { const FilePathVersionControlPair &r) {
return l.first.size() > r.first.size(); return l.first.toString().size() > r.first.toString().size();
}); });
if (allThatCanManage.isEmpty()) { if (allThatCanManage.isEmpty()) {
d->cache(nullptr, QString(), directory); // register that nothing was found! d->cache(nullptr, {}, directory); // register that nothing was found!
// report result; // report result;
if (topLevelDirectory) if (topLevelDirectory)
@@ -248,13 +249,13 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const FilePath &inpu
// In this case, don't cache it. // In this case, don't cache it.
if (!tmpDir.isEmpty()) { if (!tmpDir.isEmpty()) {
const QChar slash = QLatin1Char('/'); const QChar slash = QLatin1Char('/');
const StringVersionControlPairs::const_iterator cend = allThatCanManage.constEnd(); for (auto i = allThatCanManage.constBegin(); i != allThatCanManage.constEnd(); ++i) {
for (StringVersionControlPairs::const_iterator i = allThatCanManage.constBegin(); i != cend; ++i) { const QString firstString = i->first.toString();
// If topLevel was already cached for another VC, skip this one // If topLevel was already cached for another VC, skip this one
if (tmpDir.count() < i->first.count()) if (tmpDir.count() < firstString.count())
continue; continue;
d->cache(i->second, i->first, tmpDir); d->cache(i->second, i->first, tmpDir);
tmpDir = i->first; tmpDir = firstString;
const int slashPos = tmpDir.lastIndexOf(slash); const int slashPos = tmpDir.lastIndexOf(slash);
if (slashPos >= 0) if (slashPos >= 0)
tmpDir.truncate(slashPos); tmpDir.truncate(slashPos);
@@ -263,7 +264,7 @@ IVersionControl* VcsManager::findVersionControlForDirectory(const FilePath &inpu
// return result // return result
if (topLevelDirectory) if (topLevelDirectory)
*topLevelDirectory = FilePath::fromString(allThatCanManage.first().first); *topLevelDirectory = allThatCanManage.first().first;
IVersionControl *versionControl = allThatCanManage.first().second; IVersionControl *versionControl = allThatCanManage.first().second;
const bool isVcsConfigured = versionControl->isConfigured(); const bool isVcsConfigured = versionControl->isConfigured();
if (!isVcsConfigured || d->m_unconfiguredVcs) { if (!isVcsConfigured || d->m_unconfiguredVcs) {
@@ -303,11 +304,11 @@ FilePath VcsManager::findTopLevelForDirectory(const FilePath &directory)
return result; return result;
} }
QStringList VcsManager::repositories(const IVersionControl *vc) FilePaths VcsManager::repositories(const IVersionControl *versionControl)
{ {
QStringList result; FilePaths result;
for (auto it = d->m_cachedMatches.constBegin(); it != d->m_cachedMatches.constEnd(); ++it) { for (auto it = d->m_cachedMatches.constBegin(); it != d->m_cachedMatches.constEnd(); ++it) {
if (it.value().versionControl == vc) if (it.value().versionControl == versionControl)
result.append(it.value().topLevel); result.append(it.value().topLevel);
} }
return result; return result;

View File

@@ -46,7 +46,7 @@ public:
Utils::FilePath *topLevelDirectory = nullptr); Utils::FilePath *topLevelDirectory = nullptr);
static Utils::FilePath findTopLevelForDirectory(const Utils::FilePath &directory); static Utils::FilePath findTopLevelForDirectory(const Utils::FilePath &directory);
static QStringList repositories(const IVersionControl *); static Utils::FilePaths repositories(const IVersionControl *versionControl);
// Shows a confirmation dialog, whether the files should also be deleted // Shows a confirmation dialog, whether the files should also be deleted
// from revision control. Calls vcsDelete on the files. Returns the list // from revision control. Calls vcsDelete on the files. Returns the list

View File

@@ -10,7 +10,6 @@
#include "../gitplugin.h" #include "../gitplugin.h"
#include "../gitclient.h" #include "../gitclient.h"
#include "../gitconstants.h"
#include <vcsbase/vcsbaseconstants.h> #include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseeditor.h>
@@ -418,8 +417,7 @@ void GerritPlugin::fetch(const QSharedPointer<GerritChange> &change, int mode)
// Ask the user for a repository to retrieve the change. // Ask the user for a repository to retrieve the change.
const QString title = const QString title =
tr("Enter Local Repository for \"%1\" (%2)").arg(change->project, change->branch); tr("Enter Local Repository for \"%1\" (%2)").arg(change->project, change->branch);
const FilePath suggestedRespository = const FilePath suggestedRespository = findLocalRepository(change->project, change->branch);
FilePath::fromString(findLocalRepository(change->project, change->branch));
repository = FileUtils::getExistingDirectory(m_dialog.data(), title, suggestedRespository); repository = FileUtils::getExistingDirectory(m_dialog.data(), title, suggestedRespository);
} }
@@ -433,35 +431,34 @@ void GerritPlugin::fetch(const QSharedPointer<GerritChange> &change, int mode)
} }
// Try to find a matching repository for a project by asking the VcsManager. // Try to find a matching repository for a project by asking the VcsManager.
QString GerritPlugin::findLocalRepository(QString project, const QString &branch) const FilePath GerritPlugin::findLocalRepository(const QString &project, const QString &branch) const
{ {
const QStringList gitRepositories = VcsManager::repositories(GitPlugin::versionControl()); const FilePaths gitRepositories = VcsManager::repositories(GitPlugin::versionControl());
// Determine key (file name) to look for (qt/qtbase->'qtbase'). // Determine key (file name) to look for (qt/qtbase->'qtbase').
const int slashPos = project.lastIndexOf('/'); const int slashPos = project.lastIndexOf('/');
if (slashPos != -1) const QString fixedProject = (slashPos < 0) ? project : project.mid(slashPos + 1);
project.remove(0, slashPos + 1);
// When looking at branch 1.7, try to check folders // When looking at branch 1.7, try to check folders
// "qtbase_17", 'qtbase1.7' with a semi-smart regular expression. // "qtbase_17", 'qtbase1.7' with a semi-smart regular expression.
QScopedPointer<QRegularExpression> branchRegexp; QScopedPointer<QRegularExpression> branchRegexp;
if (!branch.isEmpty() && branch != "master") { if (!branch.isEmpty() && branch != "master") {
QString branchPattern = branch; QString branchPattern = branch;
branchPattern.replace('.', "[\\.-_]?"); branchPattern.replace('.', "[\\.-_]?");
const QString pattern = '^' + project const QString pattern = '^' + fixedProject
+ "[-_]?" + "[-_]?"
+ branchPattern + '$'; + branchPattern + '$';
branchRegexp.reset(new QRegularExpression(pattern)); branchRegexp.reset(new QRegularExpression(pattern));
if (!branchRegexp->isValid()) if (!branchRegexp->isValid())
branchRegexp.reset(); // Oops. branchRegexp.reset(); // Oops.
} }
for (const QString &repository : gitRepositories) { for (const FilePath &repository : gitRepositories) {
const QString fileName = Utils::FilePath::fromString(repository).fileName(); const QString fileName = repository.fileName();
if ((!branchRegexp.isNull() && branchRegexp->match(fileName).hasMatch()) if ((!branchRegexp.isNull() && branchRegexp->match(fileName).hasMatch())
|| fileName == project) { || fileName == fixedProject) {
// Perform a check on the branch. // Perform a check on the branch.
if (branch.isEmpty()) { if (branch.isEmpty()) {
return repository; return repository;
} else { } else {
const QString repositoryBranch = GerritPlugin::branch(FilePath::fromString(repository)); const QString repositoryBranch = GerritPlugin::branch(repository);
if (repositoryBranch.isEmpty() || repositoryBranch == branch) if (repositoryBranch.isEmpty() || repositoryBranch == branch)
return repository; return repository;
} // !branch.isEmpty() } // !branch.isEmpty()
@@ -469,9 +466,9 @@ QString GerritPlugin::findLocalRepository(QString project, const QString &branch
} // for repositories } // for repositories
// No match, do we have a projects folder? // No match, do we have a projects folder?
if (DocumentManager::useProjectsDirectory()) if (DocumentManager::useProjectsDirectory())
return DocumentManager::projectsDirectory().toString(); return DocumentManager::projectsDirectory();
return QDir::currentPath(); return FilePath::currentWorkingPath();
} }
} // namespace Internal } // namespace Internal

View File

@@ -50,7 +50,7 @@ private:
void openView(); void openView();
void push(); void push();
QString findLocalRepository(QString project, const QString &branch) const; Utils::FilePath findLocalRepository(const QString &project, const QString &branch) const;
void fetch(const QSharedPointer<GerritChange> &change, int mode); void fetch(const QSharedPointer<GerritChange> &change, int mode);
QSharedPointer<GerritParameters> m_parameters; QSharedPointer<GerritParameters> m_parameters;