Adapt to upstream changes

Change-Id: I3c55a84419b22d02bf275729220572c10ca11e35
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Orgad Shaneh
2020-01-31 14:44:33 +02:00
committed by Orgad Shaneh
parent b6f137afef
commit a565e05fb0
11 changed files with 318 additions and 433 deletions

View File

@@ -7,7 +7,6 @@ isEmpty(IDE_BUILD_TREE): error("You need to set the environment variable QTC_BUI
include($$IDE_SOURCE_TREE/src/qtcreatorplugin.pri) include($$IDE_SOURCE_TREE/src/qtcreatorplugin.pri)
SOURCES += \ SOURCES += \
fossilclient.cpp \ fossilclient.cpp \
fossilcontrol.cpp \
fossilplugin.cpp \ fossilplugin.cpp \
optionspage.cpp \ optionspage.cpp \
fossilsettings.cpp \ fossilsettings.cpp \
@@ -23,7 +22,6 @@ SOURCES += \
HEADERS += \ HEADERS += \
fossilclient.h \ fossilclient.h \
constants.h \ constants.h \
fossilcontrol.h \
fossilplugin.h \ fossilplugin.h \
optionspage.h \ optionspage.h \
fossilsettings.h \ fossilsettings.h \

View File

@@ -37,7 +37,7 @@ namespace Fossil {
namespace Internal { namespace Internal {
class FossilSettings; class FossilSettings;
class FossilControl; class FossilPluginPrivate;
class FossilClient : public VcsBase::VcsBaseClient class FossilClient : public VcsBase::VcsBaseClient
{ {
@@ -127,7 +127,7 @@ private:
VcsBase::VcsBaseEditorConfig *createLogCurrentFileEditor(VcsBase::VcsBaseEditorWidget *editor); VcsBase::VcsBaseEditorConfig *createLogCurrentFileEditor(VcsBase::VcsBaseEditorWidget *editor);
VcsBase::VcsBaseEditorConfig *createLogEditor(VcsBase::VcsBaseEditorWidget *editor); VcsBase::VcsBaseEditorConfig *createLogEditor(VcsBase::VcsBaseEditorWidget *editor);
friend class FossilControl; friend class FossilPluginPrivate;
}; };
Q_DECLARE_OPERATORS_FOR_FLAGS(FossilClient::SupportedFeatures) Q_DECLARE_OPERATORS_FOR_FLAGS(FossilClient::SupportedFeatures)

View File

@@ -1,311 +0,0 @@
/****************************************************************************
**
** Copyright (c) 2018 Artur Shepilko
** Contact: https://www.qt.io/licensing/
**
** This file is part of 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 "constants.h"
#include "fossilcontrol.h"
#include "fossilclient.h"
#include "fossilplugin.h"
#include "wizard/fossiljsextension.h"
#include <vcsbase/vcsbaseclientsettings.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcscommand.h>
#include <QFileInfo>
#include <QProcessEnvironment>
#include <QVariant>
#include <QStringList>
#include <QMap>
#include <QDir>
#include <QUrl>
namespace Fossil {
namespace Internal {
class FossilTopicCache : public Core::IVersionControl::TopicCache
{
public:
FossilTopicCache(FossilClient *client) :
m_client(client)
{ }
protected:
QString trackFile(const QString &repository) final
{
return repository + "/" + Constants::FOSSILREPO;
}
QString refreshTopic(const QString &repository) final
{
return m_client->synchronousTopic(repository);
}
private:
FossilClient *m_client;
};
FossilControl::FossilControl(FossilClient *client) :
Core::IVersionControl(new FossilTopicCache(client)),
m_client(client)
{ }
QString FossilControl::displayName() const
{
return tr("Fossil");
}
Core::Id FossilControl::id() const
{
return Core::Id(Constants::VCS_ID_FOSSIL);
}
bool FossilControl::isVcsFileOrDirectory(const Utils::FilePath &filePath) const
{
return m_client->isVcsFileOrDirectory(filePath);
}
bool FossilControl::managesDirectory(const QString &directory, QString *topLevel) const
{
QFileInfo dir(directory);
const QString topLevelFound = m_client->findTopLevelForFile(dir);
if (topLevel)
*topLevel = topLevelFound;
return !topLevelFound.isEmpty();
}
bool FossilControl::managesFile(const QString &workingDirectory, const QString &fileName) const
{
return m_client->managesFile(workingDirectory, fileName);
}
bool FossilControl::isConfigured() const
{
const Utils::FilePath binary = m_client->vcsBinary();
if (binary.isEmpty())
return false;
const QFileInfo fi = binary.toFileInfo();
if ( !(fi.exists() && fi.isFile() && fi.isExecutable()) )
return false;
// Local repositories default path must be set and exist
const QString repoPath = m_client->settings().stringValue(FossilSettings::defaultRepoPathKey);
if (repoPath.isEmpty())
return false;
const QDir dir(repoPath);
if (!dir.exists())
return false;
return true;
}
bool FossilControl::supportsOperation(Operation operation) const
{
bool supported = isConfigured();
switch (operation) {
case Core::IVersionControl::AddOperation:
case Core::IVersionControl::DeleteOperation:
case Core::IVersionControl::MoveOperation:
case Core::IVersionControl::CreateRepositoryOperation:
case Core::IVersionControl::AnnotateOperation:
case Core::IVersionControl::InitialCheckoutOperation:
break;
case Core::IVersionControl::SnapshotOperations:
supported = false;
break;
}
return supported;
}
bool FossilControl::vcsOpen(const QString &filename)
{
Q_UNUSED(filename)
return true;
}
bool FossilControl::vcsAdd(const QString &filename)
{
const QFileInfo fi(filename);
return m_client->synchronousAdd(fi.absolutePath(), fi.fileName());
}
bool FossilControl::vcsDelete(const QString &filename)
{
const QFileInfo fi(filename);
return m_client->synchronousRemove(fi.absolutePath(), fi.fileName());
}
bool FossilControl::vcsMove(const QString &from, const QString &to)
{
const QFileInfo fromInfo(from);
const QFileInfo toInfo(to);
return m_client->synchronousMove(fromInfo.absolutePath(),
fromInfo.absoluteFilePath(),
toInfo.absoluteFilePath());
}
bool FossilControl::vcsCreateRepository(const QString &directory)
{
return m_client->synchronousCreateRepository(directory);
}
bool FossilControl::vcsAnnotate(const QString &file, int line)
{
const QFileInfo fi(file);
m_client->annotate(fi.absolutePath(), fi.fileName(), QString(), line);
return true;
}
Core::ShellCommand *FossilControl::createInitialCheckoutCommand(const QString &sourceUrl,
const Utils::FilePath &baseDirectory,
const QString &localName,
const QStringList &extraArgs)
{
QMap<QString, QString> options;
FossilJsExtension::parseArgOptions(extraArgs, options);
// Two operating modes:
// 1) CloneCheckout:
// -- clone from remote-URL or a local-fossil a repository into a local-clone fossil.
// -- open/checkout the local-clone fossil
// The local-clone fossil must not point to an existing repository.
// Clone URL may be either schema-based (http, ssh, file) or an absolute local path.
//
// 2) LocalCheckout:
// -- open/checkout an existing local fossil
// Clone URL is an absolute local path and is the same as the local fossil.
const QString checkoutPath = baseDirectory.pathAppended(localName).toString();
const QString fossilFile = options.value("fossil-file");
const Utils::FilePath fossilFilePath = Utils::FilePath::fromUserInput(QDir::fromNativeSeparators(fossilFile));
const QString fossilFileNative = fossilFilePath.toUserOutput();
const QFileInfo cloneRepository(fossilFilePath.toString());
// Check when requested to clone a local repository and clone-into repository file is the same
// or not specified.
// In this case handle it as local fossil checkout request.
const QUrl url(sourceUrl);
bool isLocalRepository = (options.value("repository-type") == "localRepo");
if (url.isLocalFile() || url.isRelative()) {
const QFileInfo sourcePath(url.path());
isLocalRepository = (sourcePath.canonicalFilePath() == cloneRepository.canonicalFilePath());
}
// set clone repository admin user to configured user name
// OR override it with the specified user from clone panel
const QString adminUser = options.value("admin-user");
const bool disableAutosync = (options.value("settings-autosync") == "off");
const QString checkoutBranch = options.value("branch-tag");
// first create the checkout directory,
// as it needs to become a working directory for wizard command jobs
const QDir checkoutDir(checkoutPath);
checkoutDir.mkpath(checkoutPath);
// Setup the wizard page command job
auto command = new VcsBase::VcsCommand(checkoutDir.path(), m_client->processEnvironment());
if (!isLocalRepository
&& !cloneRepository.exists()) {
const QString sslIdentityFile = options.value("ssl-identity");
const Utils::FilePath sslIdentityFilePath = Utils::FilePath::fromUserInput(QDir::fromNativeSeparators(sslIdentityFile));
const bool includePrivate = (options.value("include-private") == "true");
QStringList extraOptions;
if (includePrivate)
extraOptions << "--private";
if (!sslIdentityFile.isEmpty())
extraOptions << "--ssl-identity" << sslIdentityFilePath.toUserOutput();
if (!adminUser.isEmpty())
extraOptions << "--admin-user" << adminUser;
// Fossil allows saving the remote address and login. This is used to
// facilitate autosync (commit/update) functionality.
// When no password is given, it prompts for that.
// When both username and password are specified, it prompts whether to
// save them.
// NOTE: In non-interactive context, these prompts won't work.
// Fossil currently does not support SSH_ASKPASS way for login query.
//
// Alternatively, "--once" option does not save the remote details.
// In such case remote details must be provided on the command-line every
// time. This also precludes autosync.
//
// So here we want Fossil to save the remote details when specified.
QStringList args;
args << m_client->vcsCommandString(FossilClient::CloneCommand)
<< extraOptions
<< sourceUrl
<< fossilFileNative;
command->addJob({m_client->vcsBinary(), args}, -1);
}
// check out the cloned repository file into the working copy directory;
// by default the latest revision is checked out
QStringList args({"open", fossilFileNative});
if (!checkoutBranch.isEmpty())
args << checkoutBranch;
command->addJob({m_client->vcsBinary(), args}, -1);
// set user default to admin user if specified
if (!isLocalRepository
&& !adminUser.isEmpty()) {
const QStringList args({ "user", "default", adminUser, "--user", adminUser});
command->addJob({m_client->vcsBinary(), args}, -1);
}
// turn-off autosync if requested
if (!isLocalRepository
&& disableAutosync) {
const QStringList args({"settings", "autosync", "off"});
command->addJob({m_client->vcsBinary(), args}, -1);
}
return command;
}
void FossilControl::changed(const QVariant &v)
{
switch (v.type()) {
case QVariant::String:
emit repositoryChanged(v.toString());
break;
case QVariant::StringList:
emit filesChanged(v.toStringList());
break;
default:
break;
}
}
} // namespace Internal
} // namespace Fossil

View File

@@ -1,77 +0,0 @@
/****************************************************************************
**
** Copyright (c) 2018 Artur Shepilko
** Contact: https://www.qt.io/licensing/
**
** This file is part of 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.
**
****************************************************************************/
#pragma once
#include <coreplugin/iversioncontrol.h>
QT_BEGIN_NAMESPACE
class QVariant;
QT_END_NAMESPACE
namespace Fossil {
namespace Internal {
class FossilClient;
//Implements just the basics of the Version Control Interface
//FossilClient handles all the work
class FossilControl: public Core::IVersionControl
{
Q_OBJECT
public:
explicit FossilControl(FossilClient *fossilClient);
QString displayName() const final;
Core::Id id() const final;
bool isVcsFileOrDirectory(const Utils::FilePath &filePath) const final;
bool managesDirectory(const QString &filename, QString *topLevel = 0) const final;
bool managesFile(const QString &workingDirectory, const QString &fileName) const final;
bool isConfigured() const final;
bool supportsOperation(Operation operation) const final;
bool vcsOpen(const QString &fileName) final;
bool vcsAdd(const QString &filename) final;
bool vcsDelete(const QString &filename) final;
bool vcsMove(const QString &from, const QString &to) final;
bool vcsCreateRepository(const QString &directory) final;
bool vcsAnnotate(const QString &file, int line) final;
Core::ShellCommand *createInitialCheckoutCommand(const QString &sourceUrl,
const Utils::FilePath &baseDirectory,
const QString &localName,
const QStringList &extraArgs) final;
// To be connected to the VcsTask's success signal to emit the repository/
// files changed signals according to the variant's type:
// String -> repository, StringList -> files
void changed(const QVariant &);
private:
FossilClient *const m_client;
};
} // namespace Internal
} // namespace Fossil

View File

@@ -131,7 +131,7 @@ QString FossilEditorWidget::decorateVersion(const QString &revision) const
const QFileInfo fi(source()); const QFileInfo fi(source());
const QString workingDirectory = fi.absolutePath(); const QString workingDirectory = fi.absolutePath();
FossilClient *client = FossilPluginPrivate::instance()->client(); const FossilClient *client = FossilPluginPrivate::instance()->client();
RevisionInfo revisionInfo = RevisionInfo revisionInfo =
client->synchronousRevisionQuery(workingDirectory, revision, true); client->synchronousRevisionQuery(workingDirectory, revision, true);
@@ -153,7 +153,7 @@ QStringList FossilEditorWidget::annotationPreviousVersions(const QString &revisi
QStringList revisions; QStringList revisions;
const QFileInfo fi(source()); const QFileInfo fi(source());
const QString workingDirectory = fi.absolutePath(); const QString workingDirectory = fi.absolutePath();
FossilClient *client = FossilPluginPrivate::instance()->client(); const FossilClient *client = FossilPluginPrivate::instance()->client();
RevisionInfo revisionInfo = RevisionInfo revisionInfo =
client->synchronousRevisionQuery(workingDirectory, revision); client->synchronousRevisionQuery(workingDirectory, revision);
if (revisionInfo.parentId.isEmpty()) if (revisionInfo.parentId.isEmpty())

View File

@@ -26,7 +26,6 @@
#include "fossilplugin.h" #include "fossilplugin.h"
#include "constants.h" #include "constants.h"
#include "fossilclient.h" #include "fossilclient.h"
#include "fossilcontrol.h"
#include "optionspage.h" #include "optionspage.h"
#include "fossilcommitwidget.h" #include "fossilcommitwidget.h"
#include "fossileditor.h" #include "fossileditor.h"
@@ -64,6 +63,7 @@
#include <vcsbase/vcsbasesubmiteditor.h> #include <vcsbase/vcsbasesubmiteditor.h>
#include <vcsbase/vcsbaseconstants.h> #include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h> #include <vcsbase/vcsoutputwindow.h>
#include <QtPlugin> #include <QtPlugin>
@@ -78,6 +78,28 @@
namespace Fossil { namespace Fossil {
namespace Internal { namespace Internal {
class FossilTopicCache : public Core::IVersionControl::TopicCache
{
public:
FossilTopicCache(FossilClient *client) :
m_client(client)
{ }
protected:
QString trackFile(const QString &repository) final
{
return repository + "/" + Constants::FOSSILREPO;
}
QString refreshTopic(const QString &repository) final
{
return m_client->synchronousTopic(repository);
}
private:
FossilClient *m_client;
};
static const VcsBase::VcsBaseEditorParameters editorParameters[] = { static const VcsBase::VcsBaseEditorParameters editorParameters[] = {
{ VcsBase::LogOutput, { VcsBase::LogOutput,
Constants::FILELOG_ID, Constants::FILELOG_ID,
@@ -105,12 +127,6 @@ static const VcsBase::VcsBaseSubmitEditorParameters submitEditorParameters = {
static FossilPluginPrivate *dd = nullptr; static FossilPluginPrivate *dd = nullptr;
FossilPluginPrivate::~FossilPluginPrivate()
{
delete m_client;
m_client = nullptr;
}
FossilPlugin::~FossilPlugin() FossilPlugin::~FossilPlugin()
{ {
delete dd; delete dd;
@@ -132,15 +148,15 @@ void FossilPlugin::extensionsInitialized()
} }
FossilPluginPrivate::FossilPluginPrivate() FossilPluginPrivate::FossilPluginPrivate()
: VcsBase::VcsBasePluginPrivate(Core::Context(Constants::FOSSIL_CONTEXT))
{ {
Core::Context context(Constants::FOSSIL_CONTEXT); Core::Context context(Constants::FOSSIL_CONTEXT);
m_client = new FossilClient(&m_fossilSettings); m_client = new FossilClient(&m_fossilSettings);
auto vcsCtrl = new FossilControl(m_client); setTopicCache(new FossilTopicCache(m_client));
initializeVcs(vcsCtrl, context); connect(m_client, &VcsBase::VcsBaseClient::changed, this, &FossilPluginPrivate::changed);
connect(m_client, &VcsBase::VcsBaseClient::changed, vcsCtrl, &FossilControl::changed);
new OptionsPage(vcsCtrl, &m_fossilSettings, this); new OptionsPage([this] { configurationChanged(); }, &m_fossilSettings, this);
const auto describeFunc = [this](const QString &source, const QString &id) { const auto describeFunc = [this](const QString &source, const QString &id) {
m_client->view(source, id); m_client->view(source, id);
@@ -170,7 +186,7 @@ FossilPluginPrivate *FossilPluginPrivate::instance()
return dd; return dd;
} }
FossilClient *FossilPluginPrivate::client() const const FossilClient *FossilPluginPrivate::client() const
{ {
return m_client; return m_client;
} }
@@ -644,7 +660,7 @@ void FossilPluginPrivate::createRepository()
return; return;
} while (true); } while (true);
// Create // Create
const bool rc = static_cast<FossilControl *>(versionControl())->vcsCreateRepository(directory); const bool rc = vcsCreateRepository(directory);
const QString nativeDir = QDir::toNativeSeparators(directory); const QString nativeDir = QDir::toNativeSeparators(directory);
if (rc) { if (rc) {
QMessageBox::information(mw, tr("Repository Created"), QMessageBox::information(mw, tr("Repository Created"),
@@ -752,6 +768,242 @@ void FossilPluginPrivate::updateActions(VcsBase::VcsBasePluginPrivate::ActionSta
repoAction->setEnabled(repoEnabled); repoAction->setEnabled(repoEnabled);
} }
QString FossilPluginPrivate::displayName() const
{
return tr("Fossil");
}
Core::Id FossilPluginPrivate::id() const
{
return Core::Id(Constants::VCS_ID_FOSSIL);
}
bool FossilPluginPrivate::isVcsFileOrDirectory(const Utils::FilePath &filePath) const
{
return m_client->isVcsFileOrDirectory(filePath);
}
bool FossilPluginPrivate::managesDirectory(const QString &directory, QString *topLevel) const
{
QFileInfo dir(directory);
const QString topLevelFound = m_client->findTopLevelForFile(dir);
if (topLevel)
*topLevel = topLevelFound;
return !topLevelFound.isEmpty();
}
bool FossilPluginPrivate::managesFile(const QString &workingDirectory, const QString &fileName) const
{
return m_client->managesFile(workingDirectory, fileName);
}
bool FossilPluginPrivate::isConfigured() const
{
const Utils::FilePath binary = m_client->vcsBinary();
if (binary.isEmpty())
return false;
const QFileInfo fi = binary.toFileInfo();
if ( !(fi.exists() && fi.isFile() && fi.isExecutable()) )
return false;
// Local repositories default path must be set and exist
const QString repoPath = m_client->settings().stringValue(FossilSettings::defaultRepoPathKey);
if (repoPath.isEmpty())
return false;
const QDir dir(repoPath);
if (!dir.exists())
return false;
return true;
}
bool FossilPluginPrivate::supportsOperation(Operation operation) const
{
bool supported = isConfigured();
switch (operation) {
case Core::IVersionControl::AddOperation:
case Core::IVersionControl::DeleteOperation:
case Core::IVersionControl::MoveOperation:
case Core::IVersionControl::CreateRepositoryOperation:
case Core::IVersionControl::AnnotateOperation:
case Core::IVersionControl::InitialCheckoutOperation:
break;
case Core::IVersionControl::SnapshotOperations:
supported = false;
break;
}
return supported;
}
bool FossilPluginPrivate::vcsOpen(const QString &filename)
{
Q_UNUSED(filename)
return true;
}
bool FossilPluginPrivate::vcsAdd(const QString &filename)
{
const QFileInfo fi(filename);
return m_client->synchronousAdd(fi.absolutePath(), fi.fileName());
}
bool FossilPluginPrivate::vcsDelete(const QString &filename)
{
const QFileInfo fi(filename);
return m_client->synchronousRemove(fi.absolutePath(), fi.fileName());
}
bool FossilPluginPrivate::vcsMove(const QString &from, const QString &to)
{
const QFileInfo fromInfo(from);
const QFileInfo toInfo(to);
return m_client->synchronousMove(fromInfo.absolutePath(),
fromInfo.absoluteFilePath(),
toInfo.absoluteFilePath());
}
bool FossilPluginPrivate::vcsCreateRepository(const QString &directory)
{
return m_client->synchronousCreateRepository(directory);
}
bool FossilPluginPrivate::vcsAnnotate(const QString &file, int line)
{
const QFileInfo fi(file);
m_client->annotate(fi.absolutePath(), fi.fileName(), QString(), line);
return true;
}
Core::ShellCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sourceUrl,
const Utils::FilePath &baseDirectory,
const QString &localName,
const QStringList &extraArgs)
{
QMap<QString, QString> options;
FossilJsExtension::parseArgOptions(extraArgs, options);
// Two operating modes:
// 1) CloneCheckout:
// -- clone from remote-URL or a local-fossil a repository into a local-clone fossil.
// -- open/checkout the local-clone fossil
// The local-clone fossil must not point to an existing repository.
// Clone URL may be either schema-based (http, ssh, file) or an absolute local path.
//
// 2) LocalCheckout:
// -- open/checkout an existing local fossil
// Clone URL is an absolute local path and is the same as the local fossil.
const QString checkoutPath = baseDirectory.pathAppended(localName).toString();
const QString fossilFile = options.value("fossil-file");
const Utils::FilePath fossilFilePath = Utils::FilePath::fromUserInput(QDir::fromNativeSeparators(fossilFile));
const QString fossilFileNative = fossilFilePath.toUserOutput();
const QFileInfo cloneRepository(fossilFilePath.toString());
// Check when requested to clone a local repository and clone-into repository file is the same
// or not specified.
// In this case handle it as local fossil checkout request.
const QUrl url(sourceUrl);
bool isLocalRepository = (options.value("repository-type") == "localRepo");
if (url.isLocalFile() || url.isRelative()) {
const QFileInfo sourcePath(url.path());
isLocalRepository = (sourcePath.canonicalFilePath() == cloneRepository.canonicalFilePath());
}
// set clone repository admin user to configured user name
// OR override it with the specified user from clone panel
const QString adminUser = options.value("admin-user");
const bool disableAutosync = (options.value("settings-autosync") == "off");
const QString checkoutBranch = options.value("branch-tag");
// first create the checkout directory,
// as it needs to become a working directory for wizard command jobs
const QDir checkoutDir(checkoutPath);
checkoutDir.mkpath(checkoutPath);
// Setup the wizard page command job
auto command = new VcsBase::VcsCommand(checkoutDir.path(), m_client->processEnvironment());
if (!isLocalRepository
&& !cloneRepository.exists()) {
const QString sslIdentityFile = options.value("ssl-identity");
const Utils::FilePath sslIdentityFilePath = Utils::FilePath::fromUserInput(QDir::fromNativeSeparators(sslIdentityFile));
const bool includePrivate = (options.value("include-private") == "true");
QStringList extraOptions;
if (includePrivate)
extraOptions << "--private";
if (!sslIdentityFile.isEmpty())
extraOptions << "--ssl-identity" << sslIdentityFilePath.toUserOutput();
if (!adminUser.isEmpty())
extraOptions << "--admin-user" << adminUser;
// Fossil allows saving the remote address and login. This is used to
// facilitate autosync (commit/update) functionality.
// When no password is given, it prompts for that.
// When both username and password are specified, it prompts whether to
// save them.
// NOTE: In non-interactive context, these prompts won't work.
// Fossil currently does not support SSH_ASKPASS way for login query.
//
// Alternatively, "--once" option does not save the remote details.
// In such case remote details must be provided on the command-line every
// time. This also precludes autosync.
//
// So here we want Fossil to save the remote details when specified.
QStringList args;
args << m_client->vcsCommandString(FossilClient::CloneCommand)
<< extraOptions
<< sourceUrl
<< fossilFileNative;
command->addJob({m_client->vcsBinary(), args}, -1);
}
// check out the cloned repository file into the working copy directory;
// by default the latest revision is checked out
QStringList args({"open", fossilFileNative});
if (!checkoutBranch.isEmpty())
args << checkoutBranch;
command->addJob({m_client->vcsBinary(), args}, -1);
// set user default to admin user if specified
if (!isLocalRepository
&& !adminUser.isEmpty()) {
const QStringList args({ "user", "default", adminUser, "--user", adminUser});
command->addJob({m_client->vcsBinary(), args}, -1);
}
// turn-off autosync if requested
if (!isLocalRepository
&& disableAutosync) {
const QStringList args({"settings", "autosync", "off"});
command->addJob({m_client->vcsBinary(), args}, -1);
}
return command;
}
void FossilPluginPrivate::changed(const QVariant &v)
{
switch (v.type()) {
case QVariant::String:
emit repositoryChanged(v.toString());
break;
case QVariant::StringList:
emit filesChanged(v.toStringList());
break;
default:
break;
}
}
} // namespace Internal } // namespace Internal
} // namespace Fossil } // namespace Fossil

View File

@@ -48,7 +48,7 @@ namespace Internal {
class OptionsPage; class OptionsPage;
class FossilClient; class FossilClient;
class FossilControl; class FossilPluginPrivate;
class FossilEditorWidget; class FossilEditorWidget;
class FossilPluginPrivate final : public VcsBase::VcsBasePluginPrivate class FossilPluginPrivate final : public VcsBase::VcsBasePluginPrivate
@@ -57,10 +57,33 @@ class FossilPluginPrivate final : public VcsBase::VcsBasePluginPrivate
public: public:
FossilPluginPrivate(); FossilPluginPrivate();
~FossilPluginPrivate();
static FossilPluginPrivate *instance(); static FossilPluginPrivate *instance();
FossilClient *client() const; const FossilClient *client() const;
// IVersionControl
QString displayName() const final;
Core::Id id() const final;
bool isVcsFileOrDirectory(const Utils::FilePath &fileName) const final;
bool managesDirectory(const QString &directory, QString *topLevel) const final;
bool managesFile(const QString &workingDirectory, const QString &fileName) const final;
bool isConfigured() const final;
bool supportsOperation(Operation operation) const final;
bool vcsOpen(const QString &fileName) final;
bool vcsAdd(const QString &fileName) final;
bool vcsDelete(const QString &filename) final;
bool vcsMove(const QString &from, const QString &to) final;
bool vcsCreateRepository(const QString &directory) final;
bool vcsAnnotate(const QString &file, int line) final;
Core::ShellCommand *createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory,
const QString &localName,
const QStringList &extraArgs) final;
protected: protected:
void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) override; void updateActions(VcsBase::VcsBasePluginPrivate::ActionState) override;
@@ -125,6 +148,11 @@ private:
QString m_submitRepository; QString m_submitRepository;
bool m_submitActionTriggered = false; bool m_submitActionTriggered = false;
// To be connected to the VcsTask's success signal to emit the repository/
// files changed signals according to the variant's type:
// String -> repository, StringList -> files
void changed(const QVariant &);
}; };
class FossilPlugin final : public ExtensionSystem::IPlugin class FossilPlugin final : public ExtensionSystem::IPlugin

View File

@@ -42,12 +42,12 @@ class OptionsPageWidget final : public Core::IOptionsPageWidget
Q_DECLARE_TR_FUNCTIONS(Fossil::Internal::OptionsPageWidget) Q_DECLARE_TR_FUNCTIONS(Fossil::Internal::OptionsPageWidget)
public: public:
OptionsPageWidget(Core::IVersionControl *control, FossilSettings *settings); OptionsPageWidget(const std::function<void()> &onApply, FossilSettings *settings);
void apply() final; void apply() final;
private: private:
Ui::OptionsPage m_ui; Ui::OptionsPage m_ui;
Core::IVersionControl *m_control; const std::function<void()> m_onApply;
FossilSettings *m_settings; FossilSettings *m_settings;
}; };
@@ -66,11 +66,11 @@ void OptionsPageWidget::apply()
return; return;
*m_settings = s; *m_settings = s;
emit m_control->configurationChanged(); m_onApply();
} }
OptionsPageWidget::OptionsPageWidget(Core::IVersionControl *control, FossilSettings *settings) : OptionsPageWidget::OptionsPageWidget(const std::function<void()> &onApply, FossilSettings *settings) :
m_control(control), m_onApply(onApply),
m_settings(settings) m_settings(settings)
{ {
m_ui.setupUi(this); m_ui.setupUi(this);
@@ -91,12 +91,12 @@ OptionsPageWidget::OptionsPageWidget(Core::IVersionControl *control, FossilSetti
m_ui.disableAutosyncCheckBox->setChecked(m_settings->boolValue(FossilSettings::disableAutosyncKey)); m_ui.disableAutosyncCheckBox->setChecked(m_settings->boolValue(FossilSettings::disableAutosyncKey));
} }
OptionsPage::OptionsPage(Core::IVersionControl *control, FossilSettings *settings, QObject *parent) : OptionsPage::OptionsPage(const std::function<void()> &onApply, FossilSettings *settings, QObject *parent) :
Core::IOptionsPage(parent) Core::IOptionsPage(parent)
{ {
setId(Constants::VCS_ID_FOSSIL); setId(Constants::VCS_ID_FOSSIL);
setDisplayName(OptionsPageWidget::tr("Fossil")); setDisplayName(OptionsPageWidget::tr("Fossil"));
setWidgetCreator([control, settings]() { return new OptionsPageWidget(control, settings); }); setWidgetCreator([onApply, settings]() { return new OptionsPageWidget(onApply, settings); });
setCategory(VcsBase::Constants::VCS_SETTINGS_CATEGORY); setCategory(VcsBase::Constants::VCS_SETTINGS_CATEGORY);
} }

View File

@@ -40,7 +40,7 @@ class OptionsPage : public Core::IOptionsPage
Q_OBJECT Q_OBJECT
public: public:
OptionsPage(Core::IVersionControl *control, FossilSettings *settings, QObject *parent); OptionsPage(const std::function<void()> &onApply, FossilSettings *settings, QObject *parent);
}; };
} // namespace Internal } // namespace Internal

View File

@@ -39,18 +39,16 @@ using namespace Core;
namespace Fossil { namespace Fossil {
namespace Internal { namespace Internal {
class FossilJsExtensionPrivate { class FossilJsExtensionPrivate {
public: public:
FossilJsExtensionPrivate() : FossilJsExtensionPrivate() :
m_vscId(Constants::VCS_ID_FOSSIL) { } m_vscId(Constants::VCS_ID_FOSSIL),
m_settings(&FossilPluginPrivate::instance()->client()->settings())
FossilClient *client() const { {
return FossilPluginPrivate::instance()->client();
} }
Core::Id m_vscId; Core::Id m_vscId;
VcsBase::VcsBaseClientSettings *m_settings;
}; };
@@ -67,7 +65,7 @@ void FossilJsExtension::parseArgOptions(const QStringList &args, QMap<QString, Q
} }
FossilJsExtension::FossilJsExtension() : FossilJsExtension::FossilJsExtension() :
d(new FossilJsExtensionPrivate) d(new FossilJsExtensionPrivate())
{ } { }
FossilJsExtension::~FossilJsExtension() FossilJsExtension::~FossilJsExtension()
@@ -92,8 +90,7 @@ QString FossilJsExtension::defaultAdminUser() const
if (!isConfigured()) if (!isConfigured())
return QString(); return QString();
VcsBase::VcsBaseClientSettings &settings = d->client()->settings(); return d->m_settings->stringValue(FossilSettings::userNameKey);
return settings.stringValue(FossilSettings::userNameKey);
} }
QString FossilJsExtension::defaultSslIdentityFile() const QString FossilJsExtension::defaultSslIdentityFile() const
@@ -101,8 +98,7 @@ QString FossilJsExtension::defaultSslIdentityFile() const
if (!isConfigured()) if (!isConfigured())
return QString(); return QString();
VcsBase::VcsBaseClientSettings &settings = d->client()->settings(); return d->m_settings->stringValue(FossilSettings::sslIdentityFileKey);
return settings.stringValue(FossilSettings::sslIdentityFileKey);
} }
QString FossilJsExtension::defaultLocalRepoPath() const QString FossilJsExtension::defaultLocalRepoPath() const
@@ -110,8 +106,7 @@ QString FossilJsExtension::defaultLocalRepoPath() const
if (!isConfigured()) if (!isConfigured())
return QString(); return QString();
VcsBase::VcsBaseClientSettings &settings = d->client()->settings(); return d->m_settings->stringValue(FossilSettings::defaultRepoPathKey);
return settings.stringValue(FossilSettings::defaultRepoPathKey);
} }
bool FossilJsExtension::defaultDisableAutosync() const bool FossilJsExtension::defaultDisableAutosync() const
@@ -119,8 +114,7 @@ bool FossilJsExtension::defaultDisableAutosync() const
if (!isConfigured()) if (!isConfigured())
return false; return false;
VcsBase::VcsBaseClientSettings &settings = d->client()->settings(); return d->m_settings->boolValue(FossilSettings::disableAutosyncKey);
return settings.boolValue(FossilSettings::disableAutosyncKey);
} }
} // namespace Internal } // namespace Internal

View File

@@ -35,6 +35,7 @@ namespace Fossil {
namespace Internal { namespace Internal {
class FossilJsExtensionPrivate; class FossilJsExtensionPrivate;
class FossilSettings;
class FossilJsExtension : public QObject class FossilJsExtension : public QObject
{ {