diff --git a/e2e/installs.test.js b/e2e/installs.test.js index 47905a942..447349fb8 100644 --- a/e2e/installs.test.js +++ b/e2e/installs.test.js @@ -4,6 +4,7 @@ const { execSync } = require('child_process'); describe('Installation', () => { let temporaryDirectory; let appPath; + const appName = 'test-app'; beforeAll(() => { temporaryDirectory = execSync( @@ -18,7 +19,7 @@ describe('Installation', () => { }); beforeEach(() => { - appPath = `${temporaryDirectory}/test-app`; + appPath = `${temporaryDirectory}/${appName}`; execSync(`mkdir ${appPath}`); }); @@ -30,6 +31,7 @@ describe('Installation', () => { test('get skipped with the `no-installation` flag', () => { execSync( `yarn start ${appPath} \ + --name ${appName} \ --template "InstantSearch.js" \ --no-installation`, { stdio: 'ignore' } @@ -43,6 +45,7 @@ describe('Installation', () => { test('without conflict generates files', () => { execSync( `yarn start ${appPath} \ + --name ${appName} \ --template "InstantSearch.js" \ --no-installation`, { stdio: 'ignore' } @@ -57,6 +60,7 @@ describe('Installation', () => { expect(() => { execSync( `yarn start ${appPath} \ + --name ${appName} \ --template "InstantSearch.js" \ --no-installation`, { stdio: 'ignore' } @@ -76,6 +80,7 @@ describe('Installation', () => { expect(() => { execSync( `yarn start ${appPath}/file \ + --name ${appName} \ --template "InstantSearch.js" \ --no-installation`, { stdio: 'ignore' } diff --git a/e2e/templates.test.js b/e2e/templates.test.js index 5a75535d9..d18cdab12 100644 --- a/e2e/templates.test.js +++ b/e2e/templates.test.js @@ -57,6 +57,7 @@ describe('Templates', () => { execSync( `yarn start ${appPath} \ + --name ${templateConfig.appName} \ --config ${configFilePath} \ --no-installation`, { stdio: 'ignore' } diff --git a/scripts/build-app.js b/scripts/build-app.js index bb98966c6..00360bbf8 100644 --- a/scripts/build-app.js +++ b/scripts/build-app.js @@ -18,8 +18,11 @@ if (!templateName) { process.exit(1); } +const appName = path.basename(appPath); + execSync( `yarn start ${appPath} \ + --name "${appName}" \ --template "${templateName}"`, { stdio: 'inherit' } ); diff --git a/src/cli/index.js b/src/cli/index.js index 38cc0da3a..212f854f2 100755 --- a/src/cli/index.js +++ b/src/cli/index.js @@ -5,6 +5,7 @@ const program = require('commander'); const inquirer = require('inquirer'); const chalk = require('chalk'); const latestSemver = require('latest-semver'); +const os = require('os'); const createInstantSearchApp = require('../api'); const { @@ -25,14 +26,14 @@ const { } = require('./getConfiguration'); const { version } = require('../../package.json'); -let appPath; +let appPathFromArgument; let options = {}; program .version(version, '-v, --version') .arguments('') .usage(`${chalk.green('')} [options]`) - .option('--name ', 'The name of the application') + .option('--name ', 'The name of the application or widget') .option('--app-id ', 'The application ID') .option('--api-key ', 'The Algolia search API key') .option('--index-name ', 'The main index of your search') @@ -49,52 +50,18 @@ program .option('--config ', 'The configuration file to get the options from') .option('--no-installation', 'Ignore dependency installation') .action((dest, opts) => { - appPath = dest; + appPathFromArgument = dest; options = opts; }) .parse(process.argv); -if (!appPath) { - console.log('Please specify the project directory:'); - console.log(); - console.log( - ` ${chalk.cyan('create-instantsearch-app')} ${chalk.green( - '' - )}` - ); - console.log(); - console.log('For example:'); - console.log( - ` ${chalk.cyan('create-instantsearch-app')} ${chalk.green( - 'my-instantsearch-app' - )}` - ); - console.log(); - console.log( - `Run ${chalk.cyan('create-instantsearch-app --help')} to see all options.` - ); - - process.exit(1); -} - -const optionsFromArguments = getOptionsFromArguments(options.rawArgs); -const appName = optionsFromArguments.name || path.basename(appPath); +const optionsFromArguments = getOptionsFromArguments(options.rawArgs || []); const attributesToDisplay = (optionsFromArguments.attributesToDisplay || '') .split(',') .filter(Boolean) .map(x => x.trim()); -try { - checkAppPath(appPath); - checkAppName(appName); -} catch (err) { - console.error(err.message); - console.log(); - - process.exit(1); -} - -const questions = { +const getQuestions = ({ appName }) => ({ application: [ { type: 'list', @@ -212,9 +179,55 @@ const questions = { }, }, ], -}; +}); async function run() { + let appPath = appPathFromArgument; + if (!appPath) { + const answers = await inquirer.prompt([ + { + type: 'input', + name: 'appPath', + message: 'Project directory', + }, + ]); + appPath = answers.appPath; + } + if (appPath.startsWith('~/')) { + appPath = path.join(os.homedir(), appPath.slice(2)); + } + try { + checkAppPath(appPath); + } catch (err) { + console.error(err.message); + console.log(); + + process.exit(1); + } + + let appName = optionsFromArguments.name; + if (!appName) { + appName = ( + await inquirer.prompt([ + { + type: 'input', + name: 'appName', + message: 'The name of the application or widget', + default: path.basename(appPath), + }, + ]) + ).appName; + } + + try { + checkAppName(appName); + } catch (err) { + console.error(err.message); + console.log(); + + process.exit(1); + } + console.log(); console.log(`Creating a new InstantSearch app in ${chalk.green(appPath)}.`); console.log(); @@ -264,7 +277,7 @@ async function run() { templateConfig.category === 'Widget' ? 'widget' : 'application'; const answers = await inquirer.prompt( - questions[implementationType].filter(question => + getQuestions({ appName })[implementationType].filter(question => isQuestionAsked({ question, args: optionsFromArguments }) ), { ...optionsFromArguments, template }