diff --git a/README.md b/README.md index bc6c415..af0c4a7 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # inquirer-select-directory -A directory prompt for Inquirer.js [inquirer](https://github.com/SBoudrias/Inquirer.js). +A directory prompt for [Inquirer.js](https://github.com/SBoudrias/Inquirer.js). This project is a fork of [Inquirer-directory](https://github.com/nicksrandall/inquirer-directory) which does not limit the navigation to the current folder. ![](https://img.shields.io/badge/license-MIT-blue.svg) -[![](https://img.shields.io/badge/release-v1.0.2-blue.svg)](https://github.com/KamiKillertO/inquirer-select-directory/releases/tag/v1.0.2) +[![](https://img.shields.io/badge/release-v1.1.0-blue.svg)](https://github.com/KamiKillertO/inquirer-select-directory/releases/tag/v1.1.0) [![Build Status](https://travis-ci.org/KamiKillertO/inquirer-select-directory.svg)](https://travis-ci.org/KamiKillertO/inquirer-select-directory) [![Build status](https://ci.appveyor.com/api/projects/status/fdyk5g3y56381742?svg=true)](https://ci.appveyor.com/project/KamiKillertO/inquirer-select-directory) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/e6a963539c4440b69356649c0048ea30)](https://www.codacy.com/app/kamikillerto/inquirer-select-directory?utm_source=github.com&utm_medium=referral&utm_content=KamiKillertO/inquirer-select-directory&utm_campaign=Badge_Grade) @@ -46,13 +46,13 @@ Change `directory` to whatever you might prefer. ### Options -Takes `type`, `name`, `message`, `basePath` properties. +Takes `type`, `name`, `message`, `basePath`, `options` properties. See [inquirer](https://github.com/SBoudrias/Inquirer.js) readme for meaning of all except **basePath**. **basePath** is the relative path from your current working directory -#### Example +#### [Example](https://github.com/KamiKillertO/inquirer-select-directory/tree/develop/example/example.js) ```javascript inquirer.registerPrompt('directory', require('inquirer-select-directory')); @@ -61,16 +61,29 @@ inquirer.prompt([{ name: 'from', message: 'Where you like to put this component?', basePath: './src' -}], function(answers) { +}]).then(function(answers) { //etc }); ``` - - + +#### options.displayHidden + +default ***false*** + +Set this to true if you to display hidden folders + +```javascript +inquirer.prompt([{ + type: 'directory', + //... + options: { + displayHidden:true + } +}]).then(function(answers) { + //etc +}); +``` + ## License -MIT +MIT \ No newline at end of file diff --git a/example/example.js b/example/example.js index 4a7e378..86892bd 100644 --- a/example/example.js +++ b/example/example.js @@ -4,13 +4,15 @@ "use strict"; var inquirer = require("inquirer"); +var fs = require('fs'); + inquirer.registerPrompt("directory", require("../src/index")); inquirer.prompt([{ type: "directory", name: "path", - message: "In what directory would like to perform this action?", - basePath: "./node_modules" -}], function(answers) { - console.log(JSON.stringify(answers, null, " ")); -}); + message: "In what directory would like to create an new file?", + basePath: "./" +}]).then(function(answers) { + fs.writeFile(answers.path + '/file.txt', 'Whoa! You have created this file'); +}); \ No newline at end of file diff --git a/package.json b/package.json index 912ecb8..0f2fe75 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "inquirer-select-directory", - "version": "1.0.2", + "version": "1.1.0", "description": "A directory prompt for Inquirer.js", "main": "src/index.js", "scripts": { @@ -39,4 +39,4 @@ "mock-fs": "3.12.1", "sinon": "1.17.2" } -} +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index 910d869..818bc26 100644 --- a/src/index.js +++ b/src/index.js @@ -52,10 +52,12 @@ function listRender(choices, pointer) { /** * Function for getting list of folders in directory - * @param {String} basePath the path the folder to get a list of containing folders - * @return {Array} array of folder names inside of basePath + * @param {String} basePath the path the folder to get a list of containing folders + * @param {Boolean} [displayHidden=false] set to true if you want to get hidden files + * @return {Array} array of folder names inside of basePath */ -function getDirectories(basePath) { +function getDirectories(basePath, displayHidden) { + displayHidden = displayHidden || false; return fs .readdirSync(basePath) .filter(function(file) { @@ -65,7 +67,10 @@ function getDirectories(basePath) { return false; } var isDir = stats.isDirectory(); - var isNotDotFile = path.basename(file).indexOf('.') !== 0; + if (displayHidden) { + return isDir; + } + var isNotDotFile = path.basename(file).indexOf(".") !== 0; return isDir && isNotDotFile; } catch (error) { return false; @@ -82,6 +87,7 @@ function Prompt() { if (!this.opt.basePath) { this.throwParamError('basePath'); } + this.opt.displayHidden = this.opt.displayHidden || false; this.currentPath = path.isAbsolute(this.opt.basePath) ? path.resolve(this.opt.basePath) : path.resolve(process.cwd(), this.opt.basePath); this.root = path.parse(this.currentPath).root; this.opt.choices = new Choices(this.createChoices(this.currentPath), this.answers); @@ -308,7 +314,7 @@ Prompt.prototype.onKeyPress = function(/*e*/) { * Helper to create new choices based on previous selection. */ Prompt.prototype.createChoices = function(basePath) { - var choices = getDirectories(basePath); + var choices = getDirectories(basePath, this.opt.displayHidden); if (basePath !== this.root) { choices.unshift(BACK); } @@ -327,3 +333,8 @@ Prompt.prototype.createChoices = function(basePath) { */ module.exports = Prompt; + + +// TODO: Add option displayHidden id:0 +// TODO: Add option displayFile id:1 +// TODO: Add theming option id:2 diff --git a/test/spec/index.spec.js b/test/spec/index.spec.js index 1ca221a..e309d99 100644 --- a/test/spec/index.spec.js +++ b/test/spec/index.spec.js @@ -9,147 +9,196 @@ var figures = require("figures"); describe("inquirer-directory", function() { - before(function() { - mock({ - "root": { - ".git": {}, - "folder1": { - "folder1-1": {} - }, - "folder2": {}, - "zfolder2": {}, - "some.png": new Buffer([8, 6, 7, 5, 3, 0, 9]), - "a-symlink": mock.symlink({ - path: "folder1" - }) - } + describe('basic feature', function() { + + + before(function() { + mock({ + "root": { + ".git": {}, + "folder1": { + "folder1-1": {} + }, + "folder2": {}, + "zfolder2": {}, + "some.png": new Buffer([8, 6, 7, 5, 3, 0, 9]), + "a-symlink": mock.symlink({ + path: "folder1" + }) + } + }); }); - }); - - after(mock.restore); - beforeEach(function() { - // need to clear "console after every action" - this.rl = new ReadlineStub(); - this.prompt = new Prompt({ - message: "Choose a directory", - name: "name", - basePath: "./root/" - }, this.rl); - }); - afterEach(function() { - this.rl.output.clear(); - }); - it("requires a basePath", function() { - expect(function() { - new Prompt({ - message: "foo", - name: "name" - }); - }).to.throw(/basePath/); - }); + after(mock.restore); - it("should list folders", function() { - this.prompt.run(); - expect(this.rl.output.__raw__).to.contain("folder1"); - expect(this.rl.output.__raw__).to.contain("folder2"); - expect(this.rl.output.__raw__).to.contain("zfolder2"); - }); + beforeEach(function() { + // need to clear "console after every action" + this.rl = new ReadlineStub(); + this.prompt = new Prompt({ + message: "Choose a directory", + name: "name", + basePath: "./root/" + }, this.rl); + }); + afterEach(function() { + this.rl.output.clear(); + }); + it("requires a basePath", function() { + expect(function() { + new Prompt({ + message: "foo", + name: "name" + }); + }).to.throw(/basePath/); + }); - it("should not contain folders starting with '.' (private folders)", function() { - this.prompt.run(); - expect(this.rl.output.__raw__).to.not.contain(".git"); - }); + it("should list folders", function() { + this.prompt.run(); + expect(this.rl.output.__raw__).to.contain("folder1"); + expect(this.rl.output.__raw__).to.contain("folder2"); + expect(this.rl.output.__raw__).to.contain("zfolder2"); + }); - it("should not contain files", function() { - this.prompt.run(); - expect(this.rl.output.__raw__).to.not.contain("some.png"); - }); + it("should not contain folders starting with '.' (private folders)", function() { + this.prompt.run(); + expect(this.rl.output.__raw__).to.not.contain(".git"); + }); - it("should allow users to drill into folder", function() { - this.prompt.run(); - this.rl.moveDown(); - this.rl.moveDown(); - this.rl.enter(); - expect(this.rl.output.__raw__).to.contain("folder1-1"); - }); + it("should not contain files", function() { + this.prompt.run(); + expect(this.rl.output.__raw__).to.not.contain("some.png"); + }); - it("should allow users to go back after drilling", function() { - this.prompt.run(); - this.rl.moveDown(); - this.rl.moveDown(); - this.rl.enter(); - expect(this.rl.output.__raw__).to.contain(".."); - this.rl.moveDown(); - expect(this.rl.output.__raw__).to.not.contain("zfolder2"); - this.rl.enter(); - expect(this.rl.output.__raw__).to.contain("zfolder2"); - }); - // - it("should allow users to go past basePath", function() { - this.prompt.run(); - this.rl.moveDown(); - this.rl.enter(); - expect(this.rl.output.__raw__).to.contain(".."); - expect(this.prompt.opt.choices.realChoices[1].name).to.equal(".."); - }); + it("should allow users to drill into folder", function() { + this.prompt.run(); + this.rl.moveDown(); + this.rl.moveDown(); + this.rl.enter(); + expect(this.rl.output.__raw__).to.contain("folder1-1"); + }); - it("should not display back option in root folder", function () { - this.prompt.run(); - while (this.prompt.currentPath !== path.parse(path.resolve(".")).root) { + it("should allow users to go back after drilling", function() { + this.prompt.run(); + this.rl.moveDown(); this.rl.moveDown(); this.rl.enter(); - } - expect(this.rl.output.__raw__).to.not.contain(".."); - }); - it("should allow users to go back using '-' shortcut", function() { - this.prompt.run(); - expect(this.rl.output.__raw__).to.contain("zfolder2"); - this.rl.keyPress("-"); - expect(this.rl.output.__raw__).to.contain(".."); - expect(this.rl.output.__raw__).to.not.contain("zfolder2"); - }); + expect(this.rl.output.__raw__).to.contain(".."); + this.rl.moveDown(); + expect(this.rl.output.__raw__).to.not.contain("zfolder2"); + this.rl.enter(); + expect(this.rl.output.__raw__).to.contain("zfolder2"); + }); + // + it("should allow users to go past basePath", function() { + this.prompt.run(); + this.rl.moveDown(); + this.rl.enter(); + expect(this.rl.output.__raw__).to.contain(".."); + expect(this.prompt.opt.choices.realChoices[1].name).to.equal(".."); + }); - it("should allow users search for a folder using '/' shortcut", function() { - this.prompt.run(); - expect(this.rl.output.__raw__).to.not.contain("Search:"); - this.rl.keyPress("/"); - expect(this.rl.output.__raw__).to.not.contain(figures.pointer + " folder1"); - expect(this.rl.output.__raw__).to.contain("Search:"); - this.rl.keyPress("f"); - - expect(this.rl.output.__raw__).to.have.string(figures.pointer + " folder1"); - this.rl.sendWord("older2"); - expect(this.rl.output.__raw__).to.contain(figures.pointer + " folder2"); - }); + it("should not display back option in root folder", function() { + this.prompt.run(); + while (this.prompt.currentPath !== path.parse(path.resolve(".")).root) { + this.rl.moveDown(); + this.rl.enter(); + } + expect(this.rl.output.__raw__).to.not.contain(".."); + }); + it("should allow users to go back using '-' shortcut", function() { + this.prompt.run(); + expect(this.rl.output.__raw__).to.contain("zfolder2"); + this.rl.keyPress("-"); + expect(this.rl.output.__raw__).to.contain(".."); + expect(this.rl.output.__raw__).to.not.contain("zfolder2"); + }); - it("should allow users to select a folder using 'choose this directory' choice", function() { - this.prompt.run(); - this.rl.moveUp(); - this.rl.enter(); - expect(this.prompt.currentPath.split(/\/|\\|\\\\/).slice(-1)[0]).to.equal("root"); - }); + it("should allow users search for a folder using '/' shortcut", function() { + this.prompt.run(); + expect(this.rl.output.__raw__).to.not.contain("Search:"); + this.rl.keyPress("/"); + expect(this.rl.output.__raw__).to.not.contain(figures.pointer + " folder1"); + expect(this.rl.output.__raw__).to.contain("Search:"); + this.rl.keyPress("f"); + + expect(this.rl.output.__raw__).to.have.string(figures.pointer + " folder1"); + this.rl.sendWord("older2"); + expect(this.rl.output.__raw__).to.contain(figures.pointer + " folder2"); + }); - it("should allow users to select a folder using '.' choice", function() { - this.prompt.run(); - this.rl.enter(); - expect(this.prompt.currentPath.split(/\/|\\|\\\\/).slice(-1)[0]).to.equal("root"); - }); + it("should allow users to select a folder using 'choose this directory' choice", function() { + this.prompt.run(); + this.rl.moveUp(); + this.rl.enter(); + expect(this.prompt.currentPath.split(/\/|\\|\\\\/).slice(-1)[0]).to.equal("root"); + }); - it('should not go back using "-" in searchMode', function() { - this.prompt.run(); - this.rl.keyPress("/"); - this.rl.keyPress("-"); - expect(this.prompt.currentPath.split(/\/|\\|\\\\/).slice(-1)[0]).to.equal("root"); - }); + it("should allow users to select a folder using '.' choice", function() { + this.prompt.run(); + this.rl.enter(); + expect(this.prompt.currentPath.split(/\/|\\|\\\\/).slice(-1)[0]).to.equal("root"); + }); - it('allow only one search instance at the time', function() { - this.prompt.run(); - this.rl.keyPress("/"); - this.rl.keyPress("a"); - this.rl.keyPress("/"); - this.rl.keyPress("b"); - expect(this.rl.output.__raw__).to.contain("Search: ab"); + it('should not go back using "-" in searchMode', function() { + this.prompt.run(); + this.rl.keyPress("/"); + this.rl.keyPress("-"); + expect(this.prompt.currentPath.split(/\/|\\|\\\\/).slice(-1)[0]).to.equal("root"); + }); + + it('allow only one search instance at the time', function() { + this.prompt.run(); + this.rl.keyPress("/"); + this.rl.keyPress("a"); + this.rl.keyPress("/"); + this.rl.keyPress("b"); + expect(this.rl.output.__raw__).to.contain("Search: ab"); + }); + // it("should allow users to press keys to shortcut to that value", function (done) { + // prompt.run(function (answer) { + // expect(answer).to.equal("zfolder2"); + // done(); + // }); + // keyPress("z"); + // enter(); + // enter(); + // }); + }); + + describe("display hidden folder", function() { + before(function() { + mock({ + "root": { + ".git": {}, + "folder1": { + "folder1-1": {} + }, + "folder2": {}, + "zfolder2": {}, + "some.png": new Buffer([8, 6, 7, 5, 3, 0, 9]), + "a-symlink": mock.symlink({ + path: "folder1" + }) + } + }); + this.rl = new ReadlineStub(); + this.prompt = new Prompt({ + message: "Choose a directory", + name: "name", + basePath: "./root/", + displayHidden: "true" + }, this.rl); + }); + + after(function() { + mock.restore(); + this.rl.output.clear(); + }); + + it("should contain folders starting with '.' (private folders)", function() { + this.prompt.run(); + expect(this.rl.output.__raw__).to.contain(".git"); + }); }); // it("should allow users to press keys to shortcut to that value", function (done) { // prompt.run(function (answer) { @@ -161,4 +210,4 @@ describe("inquirer-directory", function() { // enter(); // }); -}); +}); \ No newline at end of file