Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interactive Prompts #359

Merged
merged 3 commits into from
Sep 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 32 additions & 24 deletions src/commands/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import gittar from 'gittar';
import { green } from 'chalk';
import { prompt } from 'inquirer';
import asyncCommand from '../lib/async-command';
import { install, initGit, addScripts } from './../lib/setup';
import { info, isDir, hasCommand, error, trim, warn } from '../util';
import { install, initGit, addScripts, isMissing } from './../lib/setup';

const ORG = 'preactjs-templates';

export default asyncCommand({
command: 'create <template> <dest>',
command: 'create [template] [dest]',

desc: 'Create a new application.',

Expand Down Expand Up @@ -42,32 +42,38 @@ export default asyncCommand({
},

async handler(argv) {
// Prompt if incomplete data
if (!argv.dest || !argv.template) {
warn('Insufficient command arguments! Prompting...');
info('Alternatively, run `preact create --help` for usage info.');

let questions = isMissing(argv);
let response = await prompt(questions);
Object.assign(argv, response);
}

let isYarn = argv.yarn && hasCommand('yarn');
let cwd = argv.cwd ? resolve(argv.cwd) : process.cwd();
let target = argv.dest && resolve(cwd, argv.dest);
let exists = target && isDir(target);

if (target) {
if (exists && !argv.force) {
return error('Refusing to overwrite current directory! Please specify a different destination or use the `--force` flag', 1);
}
if (exists && !argv.force) {
return error('Refusing to overwrite current directory! Please specify a different destination or use the `--force` flag', 1);
}

if (exists && argv.force) {
let { enableForce } = await prompt({
type: 'confirm',
name: 'enableForce',
message: `You are using '--force'. Do you wish to continue?`,
default: false
});

if (enableForce) {
process.stdout.write('Initializing project in the current directory...\n');
} else {
return error('Refusing to overwrite current directory!', 1);
}
if (exists && argv.force) {
let { enableForce } = await prompt({
type: 'confirm',
name: 'enableForce',
message: `You are using '--force'. Do you wish to continue?`,
default: false
});

if (enableForce) {
info('Initializing project in the current directory!');
} else {
return error('Refusing to overwrite current directory!', 1);
}
} else {
// TODO: interactive
}

let repo = argv.template;
Expand All @@ -79,7 +85,7 @@ export default asyncCommand({
// Attempt to fetch the `template`
let archive = await gittar.fetch(repo).catch(err => {
err = err || { message:'An error occured while fetching template.' };
return error(err.code === 404 ? `Could not find repostory: ${repo}` : err.message, 1);
return error(err.code === 404 ? `Could not find repository: ${repo}` : err.message, 1);
});

let spinner = ora({
Expand Down Expand Up @@ -116,9 +122,11 @@ export default asyncCommand({
}

if (argv.name) {
spinner.text = 'Updating `name` within `package.json` file';
// Update `package.json` key
pkgData && (pkgData.name = argv.name);
if (pkgData) {
spinner.text = 'Updating `name` within `package.json` file';
pkgData.name = argv.name.toLowerCase().replace(/\s+/g, '_');
}
// Find a `manifest.json`; use the first match, if any
let files = await Promise.promisify(glob)(target + '/**/manifest.json');
let manifest = files[0] && JSON.parse(await fs.readFile(files[0]));
Expand Down
22 changes: 22 additions & 0 deletions src/lib/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,25 @@ export async function initGit(target) {
warn('Could not locate `git` binary in `$PATH`. Skipping!');
}
}

// Formulate Questions if `create` args are missing
export function isMissing(argv) {
let out = [];

const ask = (name, message, val) => {
let type = val === void 0 ? 'input' : 'confirm';
out.push({ name, message, type, default:val });
};

// Required data
!argv.template && ask('template', 'Remote template to clone (user/repo#tag)');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to show the default value here. Like what we did for preact init?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

basically its like having a fallback value for all the prompts

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no default value -- it's required.

!argv.dest && ask('dest', 'Directory to create the app');
// Extra data / flags
!argv.name && ask('name', 'The application\'s name');
!argv.force && ask('force', 'Enforce `dest` directory; will overwrite!', false);
ask('install', 'Install dependencies', true); // defaults `true`, ask anyway
!argv.yarn && ask('yarn', 'Install with `yarn` instead of `npm`', false);
!argv.git && ask('git', 'Initialize a `git` repository', false);

return out;
}