From 7efaa8c145ce3f3a140ac2570bcaf09dd39b7b13 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Fri, 4 Dec 2020 14:33:47 -0500 Subject: [PATCH 1/5] Restructure identity view to require explicit button press to accept --- lib/views/git-identity-view.js | 23 ++++++++++++++----- styles/git-identity.less | 4 +++- test/views/git-identity-view.test.js | 33 +++++++++++++++++++--------- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/lib/views/git-identity-view.js b/lib/views/git-identity-view.js index 83e648e78f..0d8cfd46d5 100644 --- a/lib/views/git-identity-view.js +++ b/lib/views/git-identity-view.js @@ -7,8 +7,11 @@ export default class GitIdentityView extends React.Component { // Model usernameBuffer: PropTypes.object.isRequired, emailBuffer: PropTypes.object.isRequired, + canWriteLocal: PropTypes.bool.isRequired, // Action methods + setLocal: PropTypes.func.isRequired, + setGlobal: PropTypes.func.isRequired, close: PropTypes.func.isRequired, }; @@ -19,19 +22,29 @@ export default class GitIdentityView extends React.Component { Git Identity

- Please set the username and email address that you wish to use to - author git commits. + Please set the username and email address that you wish to use to author git commits. This will write to the + user.name and user.email values in your git configuration at the chosen scope.

+ +
diff --git a/styles/git-identity.less b/styles/git-identity.less index 9de8483119..2371343ec3 100644 --- a/styles/git-identity.less +++ b/styles/git-identity.less @@ -26,6 +26,8 @@ } &-buttons { - // + .btn { + margin: @component-padding/2; + } } } diff --git a/test/views/git-identity-view.test.js b/test/views/git-identity-view.test.js index de0f6fb2a2..153953f327 100644 --- a/test/views/git-identity-view.test.js +++ b/test/views/git-identity-view.test.js @@ -10,6 +10,9 @@ describe('GitIdentityView', function() { {}} + setGlobal={() => {}} close={() => {}} {...override} /> @@ -30,27 +33,37 @@ describe('GitIdentityView', function() { assert.strictEqual(getEditor('email address').prop('buffer'), emailBuffer); }); - it('disables the "Continue" button if the name is blank', function() { - const usernameBuffer = new TextBuffer(); - const wrapper = mount(buildApp({usernameBuffer})); + it('disables the local repo button when canWriteLocal is false', function() { + const wrapper = mount(buildApp({canWriteLocal: false})); - assert.isTrue(wrapper.find('.btn').prop('disabled')); + assert.isTrue(wrapper.find('.btn').filterWhere(each => /this repository/.test(each.text())).prop('disabled')); }); - it('disables the "Continue" button if the email is blank', function() { - const emailBuffer = new TextBuffer(); - const wrapper = mount(buildApp({emailBuffer})); + it('triggers a callback when "Use for this repository" is clicked', function() { + const setLocal = sinon.spy(); + const wrapper = mount(buildApp({setLocal})); + + wrapper.find('.btn').filterWhere(each => /this repository/.test(each.text())).simulate('click'); + + assert.isTrue(setLocal.called); + }); + + it('triggers a callback when "Use for all repositories" is clicked', function() { + const setGlobal = sinon.spy(); + const wrapper = mount(buildApp({setGlobal})); + + wrapper.find('.btn').filterWhere(each => /all repositories/.test(each.text())).simulate('click'); - assert.isTrue(wrapper.find('.btn').prop('disabled')); + assert.isTrue(setGlobal.called); }); - it('triggers a callback when "Continue" is clicked', function() { + it('triggers a callback when "Cancel" is clicked', function() { const usernameBuffer = new TextBuffer({text: 'Me'}); const emailBuffer = new TextBuffer({text: 'me@email.com'}); const close = sinon.spy(); const wrapper = mount(buildApp({usernameBuffer, emailBuffer, close})); - wrapper.find('.btn').simulate('click'); + wrapper.find('.btn').filterWhere(each => /Cancel/.test(each.text())).simulate('click'); assert.isTrue(close.called); }); From 15d60a533544edaeda0627d67d0bebade6d2e04f Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Fri, 4 Dec 2020 14:59:45 -0500 Subject: [PATCH 2/5] Pass props in GitTabView --- lib/views/git-tab-view.js | 5 +++++ test/fixtures/props/git-tab-props.js | 2 ++ 2 files changed, 7 insertions(+) diff --git a/lib/views/git-tab-view.js b/lib/views/git-tab-view.js index 0d20431c53..e149010a1f 100644 --- a/lib/views/git-tab-view.js +++ b/lib/views/git-tab-view.js @@ -54,6 +54,8 @@ export default class GitTabView extends React.Component { tooltips: PropTypes.object.isRequired, toggleIdentityEditor: PropTypes.func.isRequired, + setLocalIdentity: PropTypes.func.isRequired, + setGlobalIdentity: PropTypes.func.isRequired, closeIdentityEditor: PropTypes.func.isRequired, openInitializeDialog: PropTypes.func.isRequired, abortMerge: PropTypes.func.isRequired, @@ -267,6 +269,9 @@ export default class GitTabView extends React.Component { ); diff --git a/test/fixtures/props/git-tab-props.js b/test/fixtures/props/git-tab-props.js index 22a9a7b343..726f659f85 100644 --- a/test/fixtures/props/git-tab-props.js +++ b/test/fixtures/props/git-tab-props.js @@ -101,6 +101,8 @@ export async function gitTabViewProps(atomEnv, repository, overrides = {}) { toggleIdentityEditor: () => {}, closeIdentityEditor: () => {}, + setLocalIdentity: () => {}, + setGlobalIdentity: () => {}, openInitializeDialog: () => {}, abortMerge: () => {}, commit: () => {}, From f229e200dfae1b1df0b506079be7e2fb1cc4624a Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Fri, 4 Dec 2020 15:00:08 -0500 Subject: [PATCH 3/5] Action methods in GitTabController --- lib/controllers/git-tab-controller.js | 27 ++++++++----------- test/controllers/git-tab-controller.test.js | 30 +++++++++++++++++++++ 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/lib/controllers/git-tab-controller.js b/lib/controllers/git-tab-controller.js index 8a2b36262b..ce4017b1c3 100644 --- a/lib/controllers/git-tab-controller.js +++ b/lib/controllers/git-tab-controller.js @@ -3,7 +3,6 @@ import path from 'path'; import React from 'react'; import PropTypes from 'prop-types'; import {TextBuffer} from 'atom'; -import {CompositeDisposable} from 'event-kit'; import GitTabView from '../views/git-tab-view'; import UserStore from '../models/user-store'; @@ -87,11 +86,6 @@ export default class GitTabController extends React.Component { login: this.props.loginModel, config: this.props.config, }); - - this.subs = new CompositeDisposable( - this.usernameBuffer.onDidStopChanging(this.setUsername), - this.emailBuffer.onDidStopChanging(this.setEmail), - ); } static getDerivedStateFromProps(props, state) { @@ -142,6 +136,8 @@ export default class GitTabController extends React.Component { toggleIdentityEditor={this.toggleIdentityEditor} closeIdentityEditor={this.closeIdentityEditor} + setLocalIdentity={this.setLocalIdentity} + setGlobalIdentity={this.setGlobalIdentity} openInitializeDialog={this.props.openInitializeDialog} openFiles={this.props.openFiles} discardWorkDirChangesForPaths={this.props.discardWorkDirChangesForPaths} @@ -371,18 +367,17 @@ export default class GitTabController extends React.Component { closeIdentityEditor = () => this.setState({editingIdentity: false}) - setUsername = () => { - const newUsername = this.usernameBuffer.getText(); - if (newUsername !== this.props.username) { - this.props.repository.setConfig('user.name', newUsername, {global: true}); - } - } + setLocalIdentity = () => this.setIdentity({}); - setEmail = () => { + setGlobalIdentity = () => this.setIdentity({global: true}); + + async setIdentity(options) { + const newUsername = this.usernameBuffer.getText(); const newEmail = this.emailBuffer.getText(); - if (newEmail !== this.props.email) { - this.props.repository.setConfig('user.email', newEmail, {global: true}); - } + + await this.props.repository.setConfig('user.name', newUsername, options); + await this.props.repository.setConfig('user.email', newEmail, options); + this.closeIdentityEditor(); } restoreFocus() { diff --git a/test/controllers/git-tab-controller.test.js b/test/controllers/git-tab-controller.test.js index d04a79c832..f943a0d6a5 100644 --- a/test/controllers/git-tab-controller.test.js +++ b/test/controllers/git-tab-controller.test.js @@ -230,6 +230,36 @@ describe('GitTabController', function() { assert.strictEqual(wrapper.find('GitTabView').prop('emailBuffer'), emailBuffer); assert.strictEqual(emailBuffer.getText(), 'changed+@email.com'); }); + + it('sets repository-local identity', async function() { + const repository = await buildRepository(await cloneRepository('three-files')); + const setConfig = sinon.stub(repository, 'setConfig'); + + const wrapper = mount(await buildApp(repository)); + + wrapper.find('GitTabView').prop('usernameBuffer').setText('changed'); + wrapper.find('GitTabView').prop('emailBuffer').setText('changed@email.com'); + + await wrapper.find('GitTabView').prop('setLocalIdentity')(); + + assert.isTrue(setConfig.calledWith('user.name', 'changed', {})); + assert.isTrue(setConfig.calledWith('user.email', 'changed@email.com', {})); + }); + + it('sets account-global identity', async function() { + const repository = await buildRepository(await cloneRepository('three-files')); + const setConfig = sinon.stub(repository, 'setConfig'); + + const wrapper = mount(await buildApp(repository)); + + wrapper.find('GitTabView').prop('usernameBuffer').setText('changed'); + wrapper.find('GitTabView').prop('emailBuffer').setText('changed@email.com'); + + await wrapper.find('GitTabView').prop('setGlobalIdentity')(); + + assert.isTrue(setConfig.calledWith('user.name', 'changed', {global: true})); + assert.isTrue(setConfig.calledWith('user.email', 'changed@email.com', {global: true})); + }); }); describe('abortMerge()', function() { From 8ed47aea8b99befdba5874977cc05a7d9f27de24 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Fri, 4 Dec 2020 15:26:32 -0500 Subject: [PATCH 4/5] Unset local config values when empty --- lib/controllers/git-tab-controller.js | 13 +++++++++++-- test/controllers/git-tab-controller.test.js | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/controllers/git-tab-controller.js b/lib/controllers/git-tab-controller.js index ce4017b1c3..66401cf589 100644 --- a/lib/controllers/git-tab-controller.js +++ b/lib/controllers/git-tab-controller.js @@ -375,8 +375,17 @@ export default class GitTabController extends React.Component { const newUsername = this.usernameBuffer.getText(); const newEmail = this.emailBuffer.getText(); - await this.props.repository.setConfig('user.name', newUsername, options); - await this.props.repository.setConfig('user.email', newEmail, options); + if (newUsername.length > 0) { + await this.props.repository.setConfig('user.name', newUsername, options); + } else { + await this.props.repository.unsetConfig('user.name'); + } + + if (newEmail.length > 0) { + await this.props.repository.setConfig('user.email', newEmail, options); + } else { + await this.props.repository.unsetConfig('user.email'); + } this.closeIdentityEditor(); } diff --git a/test/controllers/git-tab-controller.test.js b/test/controllers/git-tab-controller.test.js index f943a0d6a5..45bad35417 100644 --- a/test/controllers/git-tab-controller.test.js +++ b/test/controllers/git-tab-controller.test.js @@ -260,6 +260,21 @@ describe('GitTabController', function() { assert.isTrue(setConfig.calledWith('user.name', 'changed', {global: true})); assert.isTrue(setConfig.calledWith('user.email', 'changed@email.com', {global: true})); }); + + it('unsets config values when empty', async function() { + const repository = await buildRepository(await cloneRepository('three-files')); + const unsetConfig = sinon.stub(repository, 'unsetConfig'); + + const wrapper = mount(await buildApp(repository)); + + wrapper.find('GitTabView').prop('usernameBuffer').setText(''); + wrapper.find('GitTabView').prop('emailBuffer').setText(''); + + await wrapper.find('GitTabView').prop('setLocalIdentity')(); + + assert.isTrue(unsetConfig.calledWith('user.name')); + assert.isTrue(unsetConfig.calledWith('user.email')); + }); }); describe('abortMerge()', function() { From c5cd6012cf76df646642726686273049d67b7a6d Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Fri, 4 Dec 2020 15:34:50 -0500 Subject: [PATCH 5/5] Only unset in local config --- lib/controllers/git-tab-controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/controllers/git-tab-controller.js b/lib/controllers/git-tab-controller.js index 66401cf589..d34d42723f 100644 --- a/lib/controllers/git-tab-controller.js +++ b/lib/controllers/git-tab-controller.js @@ -375,13 +375,13 @@ export default class GitTabController extends React.Component { const newUsername = this.usernameBuffer.getText(); const newEmail = this.emailBuffer.getText(); - if (newUsername.length > 0) { + if (newUsername.length > 0 || options.global) { await this.props.repository.setConfig('user.name', newUsername, options); } else { await this.props.repository.unsetConfig('user.name'); } - if (newEmail.length > 0) { + if (newEmail.length > 0 || options.global) { await this.props.repository.setConfig('user.email', newEmail, options); } else { await this.props.repository.unsetConfig('user.email');