-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
kakha urigashvili
committed
Nov 11, 2020
1 parent
114b01e
commit a643589
Showing
15 changed files
with
345 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,3 +21,5 @@ coverage | |
# test temp | ||
test/temp | ||
|
||
autocomplete-hints.json | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/usr/bin/env node | ||
|
||
require('module-alias/register'); | ||
const commander = require('commander'); | ||
const { makeAutoCompleteCommander } = require('@src/commands/autocomplete'); | ||
const { makeSmapiCommander } = require('@src/commands/smapi/smapi-commander'); | ||
const ConfigureCommander = require('@src/commands/configure'); | ||
const DeployCommander = require('@src/commands/deploy'); | ||
const DialogCommander = require('@src/commands/dialog'); | ||
const InitCommander = require('@src/commands/init'); | ||
const NewCommander = require('@src/commands/new'); | ||
const UtilCommander = require('@src/commands/util/util-commander'); | ||
|
||
const smapiCommander = makeSmapiCommander(); | ||
const utilCommander = UtilCommander.commander; | ||
const configureCommander = ConfigureCommander.createCommand(commander); | ||
const deployCommander = DeployCommander.createCommand(commander); | ||
const newCommander = NewCommander.createCommand(commander); | ||
const initCommander = InitCommander.createCommand(commander); | ||
const dialogCommander = DialogCommander.createCommand(commander); | ||
const commanders = [smapiCommander, utilCommander, configureCommander, deployCommander, newCommander, initCommander, dialogCommander]; | ||
|
||
const autoCompleteCommander = makeAutoCompleteCommander(commanders); | ||
|
||
if (!process.argv.slice(2).length) { | ||
autoCompleteCommander.outputHelp(); | ||
} else { | ||
autoCompleteCommander.parse(process.argv); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Autocompletion | ||
|
||
## Prerequisites | ||
|
||
Autocompletion currently works for the following shells: bash, zsh and fish. | ||
|
||
For bash, please install bash-completion. | ||
|
||
``` | ||
brew install bash-completion | ||
``` | ||
|
||
And the then add the following line to ~/.bash_profile or ~/.bashrc: | ||
|
||
``` | ||
[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh" | ||
``` | ||
|
||
## Enable Autocompletion | ||
To setup auto completion, please run the following command and then restart the terminal. | ||
|
||
``` | ||
ask autocomplete setup | ||
``` | ||
|
||
|
||
## Disable Autocompletion | ||
To disable auto completion, please run the following command and then restart the terminal. | ||
|
||
``` | ||
ask autocomplete cleanup | ||
``` | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
const fs = require('fs-extra'); | ||
const path = require('path'); | ||
|
||
module.exports = class Helper { | ||
constructor(omelette, commanders = []) { | ||
this.commanders = commanders; | ||
this.completion = omelette('ask'); | ||
this.autoCompleteHintsFile = path.join(__dirname, 'autocomplete-hints.json'); | ||
} | ||
|
||
_getAutoCompleteOptions() { | ||
const options = {}; | ||
this.commanders.forEach(com => { | ||
options[com.name()] = com.commands.map(sumCom => sumCom.name()); | ||
}); | ||
|
||
return options; | ||
} | ||
|
||
/** | ||
* Initializes auto complete inside of the program | ||
*/ | ||
initAutoComplete() { | ||
if (fs.existsSync(this.autoCompleteHintsFile)) { | ||
const options = fs.readJsonSync(this.autoCompleteHintsFile); | ||
|
||
this.completion.tree(options); | ||
this.completion.init(); | ||
} | ||
} | ||
|
||
_withProcessExitDisabled(fn) { | ||
const origExit = process.exit; | ||
process.exit = () => {}; | ||
fn(); | ||
process.exit = origExit; | ||
} | ||
|
||
/** | ||
* Regenerates auto complete hints file | ||
*/ | ||
reloadAutoCompleteHints() { | ||
const options = this._getAutoCompleteOptions(); | ||
fs.writeJSONSync(this.autoCompleteHintsFile, options); | ||
} | ||
|
||
/** | ||
* Sets ups auto complete. For example, adds autocomplete entry to .bash_profile file | ||
*/ | ||
setUpAutoComplete() { | ||
this.reloadAutoCompleteHints(); | ||
this._withProcessExitDisabled(() => this.completion.setupShellInitFile()); | ||
} | ||
|
||
/** | ||
* Removes auto complete. For example, removes autocomplete entry from .bash_profile file | ||
*/ | ||
cleanUpAutoComplete() { | ||
this._withProcessExitDisabled(() => this.completion.cleanupShellInitFile()); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
const commander = require('commander'); | ||
const omelette = require('omelette'); | ||
const Messenger = require('@src/view/messenger'); | ||
const Helper = require('./helper'); | ||
|
||
/** | ||
* Initializes auto complete inside of the program | ||
*/ | ||
const initAutoComplete = () => { | ||
const helper = new Helper(omelette); | ||
helper.initAutoComplete(); | ||
}; | ||
/** | ||
* Creates auto complete commander | ||
* @param {*} commanders list of commanders used for creating an autocomplete hints file | ||
*/ | ||
const makeAutoCompleteCommander = commanders => { | ||
const program = new commander.Command(); | ||
commanders.push(program); | ||
|
||
const helper = new Helper(omelette, commanders); | ||
|
||
program._name = 'autocomplete'; | ||
program.description('sets up ask cli terminal auto completion'); | ||
|
||
program.command('setup') | ||
.description('set up auto completion') | ||
.action(() => { | ||
helper.setUpAutoComplete(); | ||
Messenger.getInstance().info('Successfully set up auto completion. Please, reload the terminal.'); | ||
}); | ||
|
||
program.command('cleanup') | ||
.description('clean up auto completion') | ||
.action(() => { | ||
helper.cleanUpAutoComplete(); | ||
Messenger.getInstance().info('Successfully removed auto completion. Please, reload the terminal.'); | ||
}); | ||
|
||
program.command('reload') | ||
.description('regenerates hints file') | ||
.action(() => { | ||
helper.reloadAutoCompleteHints(); | ||
Messenger.getInstance().info('Successfully regenerated the hints file.'); | ||
}); | ||
|
||
return program; | ||
}; | ||
|
||
module.exports = { initAutoComplete, makeAutoCompleteCommander }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
const { expect } = require('chai'); | ||
const commander = require('commander'); | ||
const EventEmitter = require('events'); | ||
const fs = require('fs-extra'); | ||
const sinon = require('sinon'); | ||
|
||
const Helper = require('@src/commands/autocomplete/helper'); | ||
|
||
describe('Commands autocomplete - helper test', () => { | ||
let helper; | ||
let setupShellInitFileStub; | ||
let cleanupShellInitFileStub; | ||
let initStub; | ||
let treeStub; | ||
let omeletteStub; | ||
|
||
const testCommander = new commander.Command(); | ||
testCommander._name = 'test'; | ||
testCommander.command('command-one'); | ||
testCommander.command('command-two'); | ||
|
||
const commanders = [testCommander]; | ||
|
||
beforeEach(() => { | ||
setupShellInitFileStub = sinon.stub(); | ||
cleanupShellInitFileStub = sinon.stub(); | ||
initStub = sinon.stub(); | ||
treeStub = sinon.stub(); | ||
|
||
omeletteStub = () => { | ||
class OmeletteStubClass extends EventEmitter { | ||
constructor() { | ||
super(); | ||
this.setupShellInitFile = setupShellInitFileStub; | ||
this.cleanupShellInitFile = cleanupShellInitFileStub; | ||
this.init = initStub; | ||
this.tree = treeStub; | ||
} | ||
} | ||
return new OmeletteStubClass(); | ||
}; | ||
|
||
helper = new Helper(omeletteStub, commanders); | ||
}); | ||
|
||
it('should set up autocomplete', () => { | ||
const writeJSONStub = sinon.stub(fs, 'writeJSONSync'); | ||
helper.setUpAutoComplete(); | ||
|
||
expect(writeJSONStub.callCount).eq(1); | ||
expect(setupShellInitFileStub.callCount).eq(1); | ||
}); | ||
|
||
it('should regenerate autocomplete hints file', () => { | ||
const writeJSONStub = sinon.stub(fs, 'writeJSONSync'); | ||
helper.reloadAutoCompleteHints(); | ||
|
||
expect(writeJSONStub.callCount).eq(1); | ||
}); | ||
|
||
it('should clean up autocomplete', () => { | ||
helper.cleanUpAutoComplete(); | ||
|
||
expect(cleanupShellInitFileStub.callCount).eq(1); | ||
}); | ||
|
||
it('should not initialize autocomplete if hint file is not present', () => { | ||
sinon.stub(fs, 'existsSync').withArgs(helper.autoCompleteHintsFile).returns(false); | ||
helper.initAutoComplete(); | ||
|
||
expect(initStub.callCount).eq(0); | ||
}); | ||
|
||
it('initialize autocomplete if hint file is present', () => { | ||
sinon.stub(fs, 'existsSync').withArgs(helper.autoCompleteHintsFile).returns(true); | ||
sinon.stub(fs, 'readJsonSync').withArgs(helper.autoCompleteHintsFile).returns({}); | ||
helper.initAutoComplete(); | ||
|
||
expect(treeStub.callCount).eq(1); | ||
expect(initStub.callCount).eq(1); | ||
}); | ||
|
||
afterEach(() => { | ||
sinon.restore(); | ||
}); | ||
}); |
Oops, something went wrong.