Skip to content

Commit

Permalink
feat: add --template flag
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesgeorge007 committed Feb 4, 2021
1 parent 0ccce89 commit c36c551
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 44 deletions.
70 changes: 31 additions & 39 deletions packages/cli/lib/commands/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ const capitalize = str => str.charAt(0).toUpperCase() + str.substring(1);

const options = [
{
name: '--name',
description: 'The application name',
name: '--template',
description: 'The template name',
},
{
name: '--cwd',
Expand Down Expand Up @@ -78,11 +78,16 @@ const options = [
];

// Formulate Questions if `create` args are missing
function requestParams(argv, templates) {
function requestParams(name, argv, templates) {
const cwd = resolve(argv.cwd);

return [
// Required data
{
type: name ? null : 'text',
name: 'name',
message: 'The name of your application',
},
{
type: argv.template ? null : 'select',
name: 'template',
Expand All @@ -96,12 +101,7 @@ function requestParams(argv, templates) {
message: 'Remote template to clone (user/repo#tag)',
},
{
type: argv.dest ? null : 'text',
name: 'dest',
message: 'Directory to create the app',
},
{
type: prev => (!dirExists(cwd, prev || argv.dest) ? null : 'confirm'),
type: !dirExists(cwd || name) ? null : 'confirm',
name: 'force',
message: 'The destination directory exists. Overwrite?',
initial: false,
Expand All @@ -114,11 +114,6 @@ function requestParams(argv, templates) {
},
},
// Extra data / flags
{
type: argv.name ? null : 'text',
name: 'name',
message: 'The name of your application',
},
{
type: 'confirm',
name: 'install',
Expand Down Expand Up @@ -206,31 +201,31 @@ async function copyFileToDestination(srcPath, destPath, force = false) {
}
}

async function command(repo, dest, argv) {
async function command(name, argv) {
validateArgs(argv, options, 'create');
// Prompt if incomplete data
if (!repo || !dest) {
if (!name || !argv.template) {
const templates = await fetchTemplates();
const questions = requestParams(argv, templates);
const questions = requestParams(name, argv, templates);
const onCancel = () => {
info('Aborting execution');
process.exit();
};
const response = await prompt(questions, { onCancel });

Object.assign(argv, response);
repo = repo || response.template;
dest = dest || response.dest;
argv.template = argv.template || response.template;
name = name || response.name;
}

if (!repo || !dest) {
if (!argv.template || !name) {
warn('Insufficient arguments!');
info('Alternatively, run `preact create --help` for usage info.');
return;
}

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

Expand All @@ -256,31 +251,28 @@ async function command(repo, dest, argv) {
}
}

// Use `--name` value or `dest` dir's name
argv.name = argv.name || dest;

let { errors } = isValidName(argv.name);
let { errors } = isValidName(name);
if (errors) {
errors.unshift(`Invalid package name: ${argv.name}`);
errors.unshift(`Invalid package name: ${name}`);
return error(errors.map(capitalize).join('\n ~ '), 1);
}

if (!repo.includes('/')) {
repo = `${ORG}/${repo}`;
info(`Assuming you meant ${repo}...`);
if (!argv.template.includes('/')) {
argv.template = `${ORG}/${argv.template}`;
info(`Assuming you meant ${argv.template}...`);
}

if (!fs.existsSync(resolve(cwd, dest, 'src'))) {
mkdirp.sync(resolve(cwd, dest, 'src'));
if (!fs.existsSync(resolve(cwd, name, 'src'))) {
mkdirp.sync(resolve(cwd, name, 'src'));
}

// Attempt to fetch the `template`
let archive = await gittar.fetch(repo).catch(err => {
let archive = await gittar.fetch(argv.template).catch(err => {
err = err || { message: 'An error occured while fetching template.' };

return error(
err.code === 404
? `Could not find repository: ${repo}`
? `Could not find repository: ${argv.template}`
: (argv.verbose && err.stack) || err.message,
1
);
Expand Down Expand Up @@ -338,7 +330,7 @@ async function command(repo, dest, argv) {
await fs.writeFile(entry, buf, enc);
}
} else {
return error(`No \`template\` directory found within ${repo}!`, 1);
return error(`No \`template\` directory found within ${argv.template}!`, 1);
}

spinner.text = 'Parsing `package.json` file';
Expand All @@ -359,17 +351,17 @@ async function command(repo, dest, argv) {
// Update `package.json` key
if (pkgData) {
spinner.text = 'Updating `name` within `package.json` file';
pkgData.name = argv.name.toLowerCase().replace(/\s+/g, '_');
pkgData.name = name.toLowerCase().replace(/\s+/g, '_');
}
// Find a `manifest.json`; use the first match, if any
let files = await glob(target + '/**/manifest.json');
let manifest = files[0] && JSON.parse(await fs.readFile(files[0]));
if (manifest) {
spinner.text = 'Updating `name` within `manifest.json` file';
manifest.name = manifest.short_name = argv.name;
manifest.name = manifest.short_name = name;
// Write changes to `manifest.json`
await fs.writeFile(files[0], JSON.stringify(manifest, null, 2));
if (argv.name.length > 12) {
if (name.length > 12) {
// @see https://developer.chrome.com/extensions/manifest/name#short_name
process.stdout.write('\n');
warn('Your `short_name` should be fewer than 12 characters.');
Expand All @@ -381,7 +373,7 @@ async function command(repo, dest, argv) {
await fs.writeFile(pkgFile, JSON.stringify(pkgData, null, 2));
}

const sourceDirectory = join(resolve(cwd, dest), 'src');
const sourceDirectory = join(resolve(cwd, name), 'src');

// Copy over template.html
const templateSrc = resolve(
Expand Down Expand Up @@ -413,7 +405,7 @@ async function command(repo, dest, argv) {
return (
trim(`
To get started, cd into the new directory:
${green('cd ' + dest)}
${green('cd ' + name)}
To start a development live-reload server:
${green(pfx + ' dev')}
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ commands.buildOptions.forEach(option => {
buildCommand.action(commands.build);

const createCommand = prog
.command('create [template] [dest]')
.command('create [name]')
.describe('Create a new application');
commands.createOptions.forEach(option => {
createCommand.option(option.name, option.description, option.default);
Expand Down
10 changes: 6 additions & 4 deletions packages/cli/tests/lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@ const argv = {
};

exports.create = async function (template, name) {
let dest = tmpDir();
const cwd = tmpDir();
name = name || `test-${template}`;

await cmd.create(template, dest, { name, cwd: '.' });
await cmd.create(name, { template, cwd, install: false });

const projectPath = join(cwd, name);

// TODO: temporary – will resolve after 2.x->3.x release
// Templates are using 2.x, which needs `.babelrc` for TEST modification.
// The 3.x templates won't need `.babelrc` for { modules: commonjs }
let babelrc = join(dest, '.babelrc');
let babelrc = join(projectPath, '.babelrc');
existsSync(babelrc) && unlinkSync(babelrc);

return dest;
return projectPath;
};

exports.build = function (cwd, options, installNodeModules = false) {
Expand Down

0 comments on commit c36c551

Please sign in to comment.