From 77a3c11f87d8fe5071a196f06fb5f465e9c47d85 Mon Sep 17 00:00:00 2001 From: Maksim Gruzdev Date: Mon, 30 Sep 2024 22:06:33 +0300 Subject: [PATCH] #70 FIX git 2.11.0 --- lib/CreateCommand.js | 6 ++---- lib/GitBranch.js | 8 ++++---- lib/GitRepo.js | 15 +++++++++++++-- lib/MrCommand.js | 11 ++++++++--- lib/OldGit.js | 38 ++++++++++++++++++++++++++++++++++++++ lib/RunCommand.js | 19 ++++++------------- lib/SwitchCommand.js | 2 +- tests/MergeCommand.js | 4 ++-- tests/MrCommand.js | 24 +++++++++++++++--------- 9 files changed, 89 insertions(+), 38 deletions(-) create mode 100644 lib/OldGit.js diff --git a/lib/CreateCommand.js b/lib/CreateCommand.js index b1e9eb4..923f527 100644 --- a/lib/CreateCommand.js +++ b/lib/CreateCommand.js @@ -10,12 +10,10 @@ module.exports = class { src = src || await defaultBranch.print() return { + confirmLabel: `Create new branch '${dst}' from '${src}' [Y/n]? `, todo: [ `git fetch`, - { - todo: `git switch --guess --merge --create ${dst} ${src}`, - confirm: `Create new branch '${dst}' from '${src}' [Y/n]? `, - }, + `git switch --guess --merge --create ${dst} ${src}`, `git config branch.${dst}.mr-target ${src}`, ] } diff --git a/lib/GitBranch.js b/lib/GitBranch.js index 0a5cd07..10dd24f 100644 --- a/lib/GitBranch.js +++ b/lib/GitBranch.js @@ -43,8 +43,8 @@ module.exports = class GitBranch { return '' } - // @todo #62:1h move to constructor - let mrSet = await this.run (`git config --default '' --get branch.${this.name}.description`) + let mrSet = await this.gitRepo.config (`branch.${this.name}.description`) + if (mrSet) { return '' } @@ -63,7 +63,7 @@ module.exports = class GitBranch { } async parentBranch () { - let parent = await this.run (`git config --default '' --get branch.${this.name}.mr-target`) + let parent = await this.gitRepo.config (`branch.${this.name}.mr-target`) if (parent) { return GitBranch.withName (parent, this.gitRepo) } @@ -71,7 +71,7 @@ module.exports = class GitBranch { } async isOriginGitlab () { - let originUrl = await this.run (`git config remote.origin.url`) + let originUrl = await this.gitRepo.config (`remote.origin.url`) return originUrl.includes ('gitlab') } diff --git a/lib/GitRepo.js b/lib/GitRepo.js index 2a73731..a330860 100644 --- a/lib/GitRepo.js +++ b/lib/GitRepo.js @@ -33,7 +33,7 @@ module.exports = class { } async toMergeAfter (branch) { - let listComma = await this.run (`git config --default '' --get branch.${branch.name}.mr-merge-after`) + let listComma = await this.config (`branch.${branch.name}.mr-merge-after`) if (!listComma) { // @todo #40:1h move all console.log to injected LogCommand console.log (`to set up premerge for branch '${branch.name}': `.padEnd (40) + `git config branch.${branch.name}.mr-merge-after test,release`) @@ -47,7 +47,7 @@ module.exports = class { return this.commandTest } - let listComma = await this.run (`git config --default '' --get mr.test`) + let listComma = await this.config (`mr.test`) if (!listComma) { console.log (`to set up prepush command: `.padEnd (40) + `git config mr.test 'npm test'`) this.commandTest = [] @@ -57,6 +57,17 @@ module.exports = class { return this.commandTest } + async config (key) { + let v + try { + v = await this.run (`git config ${key}`) + } catch (x) { + // @todo #70:1h replace catch by --default '' when git 2.11 EOL + return '' + } + return v + } + async run (cmd) { return ShellCommand.withText (cmd).runSilent () } diff --git a/lib/MrCommand.js b/lib/MrCommand.js index 20bfbf8..13be299 100644 --- a/lib/MrCommand.js +++ b/lib/MrCommand.js @@ -1,4 +1,5 @@ const GitRepo = require('./GitRepo') +const OldGit = require('./OldGit') // @todo #0:30m move to lib/commands/Push, lib/commands/Switch, etc. const Push = require('./PushCommand') const Create = require('./CreateCommand') @@ -19,22 +20,26 @@ module.exports = class MrCommand { for (let [name, clazz] of Object.entries (name2command)) { commands [name] = new clazz ({parsedArgs, gitRepo, createCommand}) } - return new MrCommand({parsedArgs, gitRepo, commands}) + const oldGit = new OldGit () + return new MrCommand({parsedArgs, gitRepo, commands, oldGit}) } constructor(o) { this.parsedArgs = o.parsedArgs this.gitRepo = o.gitRepo this.commands = o.commands + this.oldGit = o.oldGit } async todo () { - let {gitRepo, parsedArgs, commands} = this + let {oldGit, parsedArgs, commands} = this let args = await parsedArgs.value () let c = commands [args.action] if (!c) { throw new Error (`unknown action: ${args.action}!`) } - return c.todo() + let todo = await c.todo () + return oldGit.translate (todo) } + } diff --git a/lib/OldGit.js b/lib/OldGit.js new file mode 100644 index 0000000..ae72c2a --- /dev/null +++ b/lib/OldGit.js @@ -0,0 +1,38 @@ +const ShellCommand = require('./ShellCommand') + +module.exports = class OldGit { + + async translate (o) { + let v = await ShellCommand.withText (`git --version`).runSilent () + let version = v.split ('git version')[1] + + if (version > '2.23') { + return o + } + + let translated = [] + + for (let i of o.todo) { + translated = translated.concat (await this.translateCmd (i)) + } + o.todo = translated + + return o + } + + async translateCmd (cmd) { + if (/^git switch --guess --merge --create/.test (cmd)) { + return [ + cmd.split ('git switch --guess --merge --create').join ('git checkout -b'), + ] + } + if (/^git switch --guess --merge/.test (cmd)) { + return [ + 'git stash', + cmd.split ('git switch --guess --merge').join ('git checkout'), + 'git stash pop -q' + ] + } + return [cmd] + } +} diff --git a/lib/RunCommand.js b/lib/RunCommand.js index cbf97cc..f12eeb7 100644 --- a/lib/RunCommand.js +++ b/lib/RunCommand.js @@ -4,18 +4,18 @@ const UserInput = require ('./UserInput') module.exports = class { constructor(o) { - // @todo #40:2h/ARC remove typeof - this.todo = o.todo.map (i => (typeof i == "string"? {todo: i} : i)) + this.todo = o.todo + this.confirmLabel = o.confirmLabel } async confirm () { - if (this.todo.length <= 3) { + if (this.todo.length <= 4 && !this.confirmLabel) { return true } console.log (`\nOk, here is the plan:\n${await this.print ()}\n`) - return new UserInput (`Proceed [Y/n]?`).confirm () + return new UserInput (this.confirmLabel || `Proceed [Y/n]?`).confirm () } async run () { @@ -27,14 +27,7 @@ module.exports = class { for (let idx = 0; idx < this.todo.length; idx++) { let i = this.todo [idx] - if (i.confirm) { - let ok = await new UserInput (i.confirm).confirm () - if (!ok) { - throw new Error ('Aborted') - } - } - - let cmd = ShellCommand.withText (i.todo) + let cmd = ShellCommand.withText (i) try { await cmd.run () @@ -55,6 +48,6 @@ module.exports = class { async print (idx) { let tail = !idx? this.todo: this.todo.slice (idx + 1) - return tail.map (i => ` ${i.todo}`).join ('\n') + return tail.map (i => ` ${i}`).join ('\n') } } diff --git a/lib/SwitchCommand.js b/lib/SwitchCommand.js index 90be86d..a282433 100644 --- a/lib/SwitchCommand.js +++ b/lib/SwitchCommand.js @@ -20,7 +20,7 @@ module.exports = class { return { todo: [ `git fetch`, - `git switch --merge --guess ${dst}`, + `git switch --guess --merge ${dst}`, ] } } diff --git a/tests/MergeCommand.js b/tests/MergeCommand.js index 3d607e7..223ab1b 100644 --- a/tests/MergeCommand.js +++ b/tests/MergeCommand.js @@ -9,14 +9,14 @@ const ParsedArgs = require ('../lib/ParsedArgs') describe('MergeCommand', () => { let f = function () { switch (this.cmd) { - case "git config mr.master.mergeAfter --default ''": + case "git config mr.master.mergeAfter": return [GitBranch.withName ('test')] case "git push --set-upstream origin TASK-42:TASK-42": case "git push --set-upstream origin TASK-0:TASK-0": case "git push --set-upstream origin TASK-9:TASK-9": case "git push --set-upstream origin dummy:dummy": return "pushed" - case "git config --default '' --get mr.test": + case "git config mr.test": return "npm test" case "npm test": return "OK" diff --git a/tests/MrCommand.js b/tests/MrCommand.js index 1b98699..a195cca 100644 --- a/tests/MrCommand.js +++ b/tests/MrCommand.js @@ -3,6 +3,7 @@ const assert = require ('assert') const ShellCommand = require ('../lib/ShellCommand') const GitRepo = require ('../lib/GitRepo') const GitBranch = require ('../lib/GitBranch') +const OldGit = require ('../lib/OldGit') const MrCommand = require ('../lib/MrCommand') const ParsedArgs = require ('../lib/ParsedArgs') const Push = require ('../lib/PushCommand') @@ -19,7 +20,7 @@ describe('random input', () => { return `e46431c45f3c46d87c22cf63d70db2f4435bd89b refs/heads/TASK-42` case 'git branch --list TASK-43': return `` - case "git config --default '' --get mr.test": + case "git config mr.test": return `` default: throw new Error (`Unknow command: ${this.cmd}`) @@ -41,11 +42,16 @@ describe('random input', () => { return new GitBranch ({ name: 'main', origin: 'gitlab' }) }) + mock.method(OldGit.prototype, 'translate', function (o) { + return o + }) + it ('push on empty arguments', async (t) => { const parsedArgs = new ParsedArgs ([]) const gitRepo = new GitRepo () const commands = {Push: new Push ({gitRepo, parsedArgs})} - const todo = await new MrCommand ({parsedArgs, gitRepo, commands}).todo() + const oldGit = new OldGit () + const todo = await new MrCommand ({parsedArgs, gitRepo, commands, oldGit}).todo() assert.deepStrictEqual(todo, { todo: [ 'git push --set-upstream gitlab TASK-42:TASK-42' @@ -57,11 +63,12 @@ describe('random input', () => { const parsedArgs = new ParsedArgs (['TASK-42']) const gitRepo = new GitRepo () const commands = {Switch: new Switch ({gitRepo, parsedArgs})} - const todo = await new MrCommand ({parsedArgs, gitRepo, commands}).todo() + const oldGit = new OldGit () + const todo = await new MrCommand ({parsedArgs, gitRepo, commands, oldGit}).todo() assert.deepStrictEqual(todo, { todo: [ 'git fetch', - 'git switch --merge --guess TASK-42', + 'git switch --guess --merge TASK-42', ] }) }) @@ -70,15 +77,14 @@ describe('random input', () => { const parsedArgs = new ParsedArgs (['TASK-43']) const gitRepo = new GitRepo () const createCommand = new Create ({gitRepo, parsedArgs}) + const oldGit = new OldGit () const commands = {Switch: new Switch ({gitRepo, parsedArgs, createCommand})} - const todo = await new MrCommand ({parsedArgs, gitRepo, commands}).todo() + const todo = await new MrCommand ({parsedArgs, gitRepo, commands, oldGit}).todo() assert.deepStrictEqual(todo, { + confirmLabel: `Create new branch 'TASK-43' from 'gitlab/main' [Y/n]? `, todo: [ 'git fetch', - { - todo: 'git switch --guess --merge --create TASK-43 gitlab/main', - confirm: "Create new branch 'TASK-43' from 'gitlab/main' [Y/n]? ", - }, + 'git switch --guess --merge --create TASK-43 gitlab/main', `git config branch.TASK-43.mr-target gitlab/main` ] })