Skip to content
This repository was archived by the owner on Dec 16, 2022. It is now read-only.

Commit d5a5655

Browse files
Eunjae LeeHaroenv
andauthored
feat(cli): make app path optional (#457)
Co-authored-by: Haroen Viaene <[email protected]>
1 parent 813c7bf commit d5a5655

File tree

4 files changed

+64
-42
lines changed

4 files changed

+64
-42
lines changed

e2e/installs.test.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const { execSync } = require('child_process');
44
describe('Installation', () => {
55
let temporaryDirectory;
66
let appPath;
7+
const appName = 'test-app';
78

89
beforeAll(() => {
910
temporaryDirectory = execSync(
@@ -18,7 +19,7 @@ describe('Installation', () => {
1819
});
1920

2021
beforeEach(() => {
21-
appPath = `${temporaryDirectory}/test-app`;
22+
appPath = `${temporaryDirectory}/${appName}`;
2223
execSync(`mkdir ${appPath}`);
2324
});
2425

@@ -30,6 +31,7 @@ describe('Installation', () => {
3031
test('get skipped with the `no-installation` flag', () => {
3132
execSync(
3233
`yarn start ${appPath} \
34+
--name ${appName} \
3335
--template "InstantSearch.js" \
3436
--no-installation`,
3537
{ stdio: 'ignore' }
@@ -43,6 +45,7 @@ describe('Installation', () => {
4345
test('without conflict generates files', () => {
4446
execSync(
4547
`yarn start ${appPath} \
48+
--name ${appName} \
4649
--template "InstantSearch.js" \
4750
--no-installation`,
4851
{ stdio: 'ignore' }
@@ -57,6 +60,7 @@ describe('Installation', () => {
5760
expect(() => {
5861
execSync(
5962
`yarn start ${appPath} \
63+
--name ${appName} \
6064
--template "InstantSearch.js" \
6165
--no-installation`,
6266
{ stdio: 'ignore' }
@@ -76,6 +80,7 @@ describe('Installation', () => {
7680
expect(() => {
7781
execSync(
7882
`yarn start ${appPath}/file \
83+
--name ${appName} \
7984
--template "InstantSearch.js" \
8085
--no-installation`,
8186
{ stdio: 'ignore' }

e2e/templates.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ describe('Templates', () => {
6060

6161
execSync(
6262
`yarn start ${appPath} \
63+
--name ${templateConfig.appName} \
6364
--config ${configFilePath} \
6465
--no-installation`,
6566
{ stdio: 'ignore' }

scripts/build-app.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ if (!templateName) {
1818
process.exit(1);
1919
}
2020

21+
const appName = path.basename(appPath);
22+
2123
execSync(
2224
`yarn start ${appPath} \
25+
--name "${appName}" \
2326
--template "${templateName}"`,
2427
{ stdio: 'inherit' }
2528
);

src/cli/index.js

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const program = require('commander');
55
const inquirer = require('inquirer');
66
const chalk = require('chalk');
77
const latestSemver = require('latest-semver');
8+
const os = require('os');
89

910
const createInstantSearchApp = require('../api');
1011
const {
@@ -25,14 +26,14 @@ const {
2526
} = require('./getConfiguration');
2627
const { version } = require('../../package.json');
2728

28-
let appPath;
29+
let appPathFromArgument;
2930
let options = {};
3031

3132
program
3233
.version(version, '-v, --version')
3334
.arguments('<project-directory>')
3435
.usage(`${chalk.green('<project-directory>')} [options]`)
35-
.option('--name <name>', 'The name of the application')
36+
.option('--name <name>', 'The name of the application or widget')
3637
.option('--app-id <appId>', 'The application ID')
3738
.option('--api-key <apiKey>', 'The Algolia search API key')
3839
.option('--index-name <indexName>', 'The main index of your search')
@@ -49,52 +50,18 @@ program
4950
.option('--config <config>', 'The configuration file to get the options from')
5051
.option('--no-installation', 'Ignore dependency installation')
5152
.action((dest, opts) => {
52-
appPath = dest;
53+
appPathFromArgument = dest;
5354
options = opts;
5455
})
5556
.parse(process.argv);
5657

57-
if (!appPath) {
58-
console.log('Please specify the project directory:');
59-
console.log();
60-
console.log(
61-
` ${chalk.cyan('create-instantsearch-app')} ${chalk.green(
62-
'<project-directory>'
63-
)}`
64-
);
65-
console.log();
66-
console.log('For example:');
67-
console.log(
68-
` ${chalk.cyan('create-instantsearch-app')} ${chalk.green(
69-
'my-instantsearch-app'
70-
)}`
71-
);
72-
console.log();
73-
console.log(
74-
`Run ${chalk.cyan('create-instantsearch-app --help')} to see all options.`
75-
);
76-
77-
process.exit(1);
78-
}
79-
80-
const optionsFromArguments = getOptionsFromArguments(options.rawArgs);
81-
const appName = optionsFromArguments.name || path.basename(appPath);
58+
const optionsFromArguments = getOptionsFromArguments(options.rawArgs || []);
8259
const attributesToDisplay = (optionsFromArguments.attributesToDisplay || '')
8360
.split(',')
8461
.filter(Boolean)
8562
.map(x => x.trim());
8663

87-
try {
88-
checkAppPath(appPath);
89-
checkAppName(appName);
90-
} catch (err) {
91-
console.error(err.message);
92-
console.log();
93-
94-
process.exit(1);
95-
}
96-
97-
const questions = {
64+
const getQuestions = ({ appName }) => ({
9865
application: [
9966
{
10067
type: 'list',
@@ -212,9 +179,55 @@ const questions = {
212179
},
213180
},
214181
],
215-
};
182+
});
216183

217184
async function run() {
185+
let appPath = appPathFromArgument;
186+
if (!appPath) {
187+
const answers = await inquirer.prompt([
188+
{
189+
type: 'input',
190+
name: 'appPath',
191+
message: 'Project directory',
192+
},
193+
]);
194+
appPath = answers.appPath;
195+
}
196+
if (appPath.startsWith('~/')) {
197+
appPath = path.join(os.homedir(), appPath.slice(2));
198+
}
199+
try {
200+
checkAppPath(appPath);
201+
} catch (err) {
202+
console.error(err.message);
203+
console.log();
204+
205+
process.exit(1);
206+
}
207+
208+
let appName = optionsFromArguments.name;
209+
if (!appName) {
210+
appName = (
211+
await inquirer.prompt([
212+
{
213+
type: 'input',
214+
name: 'appName',
215+
message: 'The name of the application or widget',
216+
default: path.basename(appPath),
217+
},
218+
])
219+
).appName;
220+
}
221+
222+
try {
223+
checkAppName(appName);
224+
} catch (err) {
225+
console.error(err.message);
226+
console.log();
227+
228+
process.exit(1);
229+
}
230+
218231
console.log();
219232
console.log(`Creating a new InstantSearch app in ${chalk.green(appPath)}.`);
220233
console.log();
@@ -264,7 +277,7 @@ async function run() {
264277
templateConfig.category === 'Widget' ? 'widget' : 'application';
265278

266279
const answers = await inquirer.prompt(
267-
questions[implementationType].filter(question =>
280+
getQuestions({ appName })[implementationType].filter(question =>
268281
isQuestionAsked({ question, args: optionsFromArguments })
269282
),
270283
{ ...optionsFromArguments, template }

0 commit comments

Comments
 (0)