Commit 2df0558b authored by Artur Puzio's avatar Artur Puzio Committed by Kevin Funk
Browse files

Git: Display dialog to configure user & name

Summary:
Added function to get git config
Added checking of `user.email` and `user.name` when committing
Added possibility to configure global git parameters
Added `QDialog` extension to choose the name and email, with possibility to save the settings as global and validation.
Used the extension to handle the lack of `user.name` or `user.email` configured when committing.
Added unit tests for readConfigOption and setConfigOption.
This fixes the [[ https://bugs.kde.org/show_bug.cgi?id=347351 | Bug 347351 ]]

Test Plan:
The new dialog works fine.
Tests pass.

BUG: 347351
FIXED-IN: 5.0

Reviewers: kfunk

Reviewed By: kfunk

Subscribers: mwolff, kdevelop-devel

Differential Revision: https://phabricator.kde.org/D852
parent b0551beb
......@@ -12,8 +12,10 @@ set(kdevgit_PART_SRCS
gitpluginmetadata.cpp
gitjob.cpp
gitplugincheckinrepositoryjob.cpp
gitnameemaildialog.cpp
)
ki18n_wrap_ui(kdevgit_PART_SRCS stashmanagerdialog.ui)
ki18n_wrap_ui(kdevgit_PART_SRCS gitnameemaildialog.ui)
kdevplatform_add_plugin(kdevgit JSON kdevgit.json SOURCES ${kdevgit_PART_SRCS})
target_link_libraries(kdevgit
KDev::Util
......
/**************************************************************************
* Copyright 2016 Artur Puzio <cytadela88@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "gitnameemaildialog.h"
#include "ui_gitnameemaildialog.h"
#include <QDialog>
#include <KLocalizedString>
#include "gitplugin.h"
using namespace KDevelop;
GitNameEmailDialog::GitNameEmailDialog(QWidget *parent)
: QDialog(parent),
ui(new Ui::GitNameEmailDialog)
{
ui->setupUi(this);
ui->submitButton->setDisabled(true);
connect(ui->submitButton, &QPushButton::clicked, this, &GitNameEmailDialog::accept);
connect(ui->cancelButton, &QPushButton::clicked, this, &GitNameEmailDialog::reject);
QRegularExpression rx(".+");
auto validator = new QRegularExpressionValidator(rx, this);
ui->emailEdit->setValidator(validator);
ui->nameEdit->setValidator(validator);
connect(ui->emailEdit, &QLineEdit::textChanged, this, &GitNameEmailDialog::updateUi);
connect(ui->nameEdit, &QLineEdit::textChanged, this, &GitNameEmailDialog::updateUi);
}
GitNameEmailDialog::~GitNameEmailDialog() = default;
void GitNameEmailDialog::updateUi()
{
ui->submitButton->setDisabled(!ui->nameEdit->hasAcceptableInput() or
!ui->emailEdit->hasAcceptableInput());
}
void GitNameEmailDialog::setName(const QString& name)
{
ui->nameEdit->setText(name);
}
void GitNameEmailDialog::setEmail(const QString& email)
{
ui->emailEdit->setText(email);
}
QString GitNameEmailDialog::name() const
{
return ui->nameEdit->text();
}
QString GitNameEmailDialog::email() const
{
return ui->emailEdit->text();
}
bool GitNameEmailDialog::isGlobal() const
{
return ui->globalCheckBox->isChecked();
}
#include "gitnameemaildialog.moc"
/**************************************************************************
* Copyright 2016 Artur Puzio <cytadela88@gmail.com> *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#ifndef KDEVPLATFORM_PLUGIN_GIT_NAMEEMAILDIALOG_H
#define KDEVPLATFORM_PLUGIN_GIT_NAMEEMAILDIALOG_H
#include <QtWidgets>
#include <QDialog>
class QCheckBox;
class QDialogButtonBox;
class QGroupBox;
class QLabel;
class QLineEdit;
class QPushButton;
namespace Ui { class GitNameEmailDialog; }
class GitNameEmailDialog : public QDialog
{
Q_OBJECT
public:
explicit GitNameEmailDialog(QWidget *parent = 0);
~GitNameEmailDialog() override;
void setName(const QString& name);
void setEmail(const QString& email);
QString name() const;
QString email() const;
bool isGlobal() const;
private slots:
void updateUi();
private:
QScopedPointer<Ui::GitNameEmailDialog> ui;
};
#endif //KDEVPLATFORM_PLUGIN_GIT_NAMEEMAILDIALOG_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GitNameEmailDialog</class>
<widget class="QDialog" name="GitNameEmailDialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>308</width>
<height>216</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="windowTitle">
<string>Git name and email</string>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>308</width>
<height>216</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>3</number>
</property>
<property name="topMargin">
<number>3</number>
</property>
<property name="rightMargin">
<number>3</number>
</property>
<property name="bottomMargin">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="descriptionLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;You have not yet configured the name and email to be associated with your Git commits.&lt;br/&gt;The values you enter here will be written to the Git configuration, either locally for the current project only, or globally for all Git projects.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Name</string>
</property>
<property name="buddy">
<cstring>nameEdit</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="nameEdit"/>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="emailEdit"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Emai&amp;l</string>
</property>
<property name="buddy">
<cstring>emailEdit</cstring>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="globalCheckBox">
<property name="text">
<string>Global</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="submitButton">
<property name="text">
<string>Set</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
......@@ -56,6 +56,7 @@
#include "gitjob.h"
#include "gitmessagehighlighter.h"
#include "gitplugincheckinrepositoryjob.h"
#include "gitnameemaildialog.h"
#include "debug.h"
Q_LOGGING_CATEGORY(PLUGIN_GIT, "kdevplatform.plugins.git")
......@@ -420,8 +421,23 @@ VcsJob* GitPlugin::commit(const QString& message,
{
if (localLocations.empty() || message.isEmpty())
return errorsFound(i18n("No files or message specified"));
QDir dir = dotGitDirectory(localLocations.front());
QUrl url = QUrl::fromLocalFile(dir.absolutePath());
{
QString name = readConfigOption(url, QStringLiteral("user.name"));
QString email = readConfigOption(url, QStringLiteral("user.email"));
if (email.isEmpty() || name.isEmpty()) {
GitNameEmailDialog dialog;
dialog.setName(name);
dialog.setEmail(email);
if (dialog.exec()) {
setConfigOption(url, QStringLiteral("user.name"), dialog.name(), dialog.isGlobal())->exec();
setConfigOption(url, QStringLiteral("user.email"), dialog.email(), dialog.isGlobal())->exec();
} else {
return errorsFound(i18n("Email or name for git not specified"));
}
}
}
DVcsJob* job = new DVcsJob(dir, this);
job->setType(VcsJob::Commit);
QList<QUrl> files = (recursion == IBasicVersionControl::Recursive ? localLocations : preventRecursion(localLocations));
......@@ -1455,11 +1471,25 @@ CheckInRepositoryJob* GitPlugin::isInRepository(KTextEditor::Document* document)
return job;
}
DVcsJob* GitPlugin::setConfigOption(const QUrl& repository, const QString& key, const QString& value)
DVcsJob* GitPlugin::setConfigOption(const QUrl& repository, const QString& key, const QString& value, bool global)
{
auto job = new DVcsJob(urlDir(repository), this);
*job << "git" << "config" << key << value;
QStringList args;
args << "git" << "config";
if(global)
args << "--global";
args << key << value;
*job << args;
return job;
}
QString GitPlugin::readConfigOption(const QUrl& repository, const QString& key)
{
QProcess exec;
exec.setWorkingDirectory(urlDir(repository).absolutePath());
exec.start("git", QStringList() << "config" << "--get" << key);
exec.waitForFinished();
return exec.readAllStandardOutput().trimmed();
}
#include "gitplugin.moc"
......@@ -145,7 +145,8 @@ public:
KDevelop::CheckInRepositoryJob* isInRepository(KTextEditor::Document* document) override;
KDevelop::DVcsJob* setConfigOption(const QUrl& repository, const QString& key, const QString& value);
KDevelop::DVcsJob* setConfigOption(const QUrl& repository, const QString& key, const QString& value, bool global = false);
QString readConfigOption(const QUrl& repository, const QString& key);
// this indicates whether the diff() function will generate a diff (patch) which
// includes the working copy directory name or not (in which case git diff is called
......
......@@ -13,8 +13,10 @@ if (GIT_FOUND)
../gitjob.cpp
../gitmessagehighlighter.cpp
../gitplugincheckinrepositoryjob.cpp
../gitnameemaildialog.cpp
)
ki18n_wrap_ui(gittest_SRCS ../stashmanagerdialog.ui)
ki18n_wrap_ui(gittest_SRCS ../gitnameemaildialog.ui)
ecm_add_test(${gittest_SRCS}
TEST_NAME test_kdevgit
LINK_LIBRARIES Qt5::Test KDev::Vcs KDev::Util KDev::Tests
......
......@@ -233,6 +233,35 @@ void GitInitTest::testInit()
repoInit();
}
void GitInitTest::testLocalConfig()
{
repoInit();
qDebug() << "read notexisting.asdads";
QString pluginRead1 = m_plugin->readConfigOption(QUrl::fromLocalFile(gitTest_BaseDir()), QStringLiteral("notexisting.asdads"));
QCOMPARE(pluginRead1, QStringLiteral(""));
qDebug() << "write user.name = \"John Tester\"";
auto job = m_plugin->setConfigOption(QUrl::fromLocalFile(gitTest_BaseDir()), QStringLiteral("user.name"), QStringLiteral("John Tester"));
VERIFYJOB(job);
QProcess myRead1;
myRead1.setWorkingDirectory(gitTest_BaseDir());
myRead1.start("git", QStringList() << "config" << "--get" << QStringLiteral("user.name"));
myRead1.waitForFinished();
QString myRead1result = myRead1.readAllStandardOutput().trimmed();
QCOMPARE(myRead1result, QStringLiteral("John Tester"));
qDebug() << "read user.name";
QString pluginRead2 = m_plugin->readConfigOption(QUrl::fromLocalFile(gitTest_BaseDir()), QStringLiteral("user.name"));
QProcess myRead2;
myRead2.setWorkingDirectory(gitTest_BaseDir());
myRead2.start("git", QStringList() << "config" << "--get" << QStringLiteral("user.name"));
myRead2.waitForFinished();
QCOMPARE(pluginRead2, QStringLiteral("John Tester"));
QString myRead2result = myRead2.readAllStandardOutput().trimmed();
QCOMPARE(myRead2result, QStringLiteral("John Tester"));
}
void GitInitTest::testAdd()
{
repoInit();
......
......@@ -51,6 +51,7 @@ private slots:
void cleanup();
void testInit();
void testLocalConfig();
void testAdd();
void testCommit();
void testBranching();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment