Skip to content

Commit 80fbd27

Browse files
committed
fix(new): improve experience of new command
This commit renames the "filename" argument to "namespace", creates the assets folder only when assets exist and skips installing dependencies if unnecessary re: #20
1 parent a9f3fd2 commit 80fbd27

File tree

2 files changed

+55
-34
lines changed

2 files changed

+55
-34
lines changed

src/commands/new.ts

+15-14
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ import prompts from 'prompts';
55
import { Merge } from 'type-fest';
66
import { Arguments, Argv } from 'yargs';
77
import checkProjectStructure from '../checks/project-structure';
8+
import { downloadTemplate, fetchListOfTemplates } from '../templating/actions';
89
import { CliInfo } from './types';
910
import { getFullCommand } from './utils';
10-
import { downloadTemplate, fetchListOfTemplates } from '../templating/actions';
1111

1212
export type NewCliFlags = Arguments<{
13-
filename?: string;
13+
namespace?: string;
1414
template?: string;
1515
list?: string;
1616
}>;
1717

1818
export type NewConfig = Merge<
1919
NewCliFlags,
2020
{
21-
filename?: string;
21+
namespace?: string;
2222
template?: string;
2323
}
2424
>;
@@ -62,11 +62,12 @@ async function getMissingInfo(flags: NewCliFlags): Promise<NewConfig> {
6262
});
6363
}
6464

65-
if (!flags.filename) {
65+
if (!flags.namespace) {
6666
questions.push({
6767
type: 'text',
68-
name: 'filename',
69-
message: 'What should be the name of your function?',
68+
name: 'namespace',
69+
message:
70+
'What should be the namespace your function(s) are placed under?',
7071
validate: (input: string) => {
7172
if (input.length < 1 || input.includes(' ')) {
7273
return 'Your name cannot include whitespace';
@@ -79,7 +80,7 @@ async function getMissingInfo(flags: NewCliFlags): Promise<NewConfig> {
7980
if (questions.length === 0) {
8081
return {
8182
...flags,
82-
filename: flags.filename,
83+
namespace: flags.namespace,
8384
template: flags.template,
8485
};
8586
}
@@ -88,7 +89,7 @@ async function getMissingInfo(flags: NewCliFlags): Promise<NewConfig> {
8889
return {
8990
...flags,
9091
template: flags.template || answers.template,
91-
filename: flags.filename || answers.filename,
92+
namespace: flags.namespace || answers.namespace,
9293
};
9394
}
9495

@@ -120,17 +121,17 @@ export async function handler(flagsInput: NewCliFlags): Promise<void> {
120121
const flags = await getMissingInfo(flagsInput);
121122

122123
if (
123-
typeof flags.filename === 'undefined' ||
124-
flags.filename.length === 0 ||
124+
typeof flags.namespace === 'undefined' ||
125+
flags.namespace.length === 0 ||
125126
typeof flags.template === 'undefined' ||
126-
flags.filename.length === 0
127+
flags.namespace.length === 0
127128
) {
128129
return;
129130
}
130131

131-
const bundleName = flags.filename.replace(/\.js$/, '');
132+
const sanitizedNamespace = flags.namespace.replace(/\.js$/, '');
132133

133-
downloadTemplate(flags.template, bundleName, targetDirectory);
134+
downloadTemplate(flags.template, sanitizedNamespace, targetDirectory);
134135
}
135136

136137
export const cliInfo: CliInfo = {
@@ -162,7 +163,7 @@ function optionBuilder(yargs: Argv<any>): Argv<NewCliFlags> {
162163
return yargs;
163164
}
164165

165-
export const command = ['new [filename]', 'template [filename]'];
166+
export const command = ['new [namespace]', 'template [namespace]'];
166167
export const describe =
167168
'Creates a new Twilio Function based on an existing template';
168169
export const builder = optionBuilder;

src/templating/filesystem.ts

+40-20
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
import { fsHelpers } from '@twilio-labs/serverless-api';
22
import chalk from 'chalk';
3+
import debug from 'debug';
34
import dotenv from 'dotenv';
5+
import { mkdir as oldMkdir } from 'fs';
46
import got from 'got';
57
import Listr, { ListrTask } from 'listr';
68
import path from 'path';
79
import { install, InstallResult } from 'pkg-install';
10+
import { promisify } from 'util';
811
import { downloadFile, fileExists, readFile, writeFile } from '../utils/fs';
912
import { TemplateFileInfo } from './data';
10-
import { mkdir as oldMkdir } from 'fs';
11-
import { promisify } from 'util';
1213
const mkdir = promisify(oldMkdir);
1314

15+
const log = debug('twilio-run:templating:filesystem');
16+
1417
async function writeEnvFile(
1518
contentUrl: string,
1619
targetDir: string,
@@ -59,12 +62,23 @@ async function writeEnvFile(
5962
async function installDependencies(
6063
contentUrl: string,
6164
targetDir: string
62-
): Promise<InstallResult> {
65+
): Promise<InstallResult | undefined> {
6366
const pkgContent = await got(contentUrl, { json: true });
6467
const dependencies = pkgContent.body.dependencies;
65-
return install(dependencies, {
66-
cwd: targetDir,
67-
});
68+
if (dependencies && Object.keys(dependencies).length > 0) {
69+
return install(dependencies, {
70+
cwd: targetDir,
71+
});
72+
}
73+
}
74+
75+
function hasFilesOfType(files: TemplateFileInfo[], type: string) {
76+
for (let file of files) {
77+
if (file.type === type) {
78+
return true;
79+
}
80+
}
81+
return false;
6882
}
6983

7084
export async function writeFiles(
@@ -82,22 +96,28 @@ export async function writeFiles(
8296
]);
8397
const functionsTargetDir = path.join(functionsDir, bundleName);
8498
const assetsTargetDir = path.join(assetsDir, bundleName);
99+
85100
if (functionsTargetDir !== functionsDir) {
86-
try {
87-
await mkdir(functionsTargetDir);
88-
} catch (err) {
89-
console.error(err);
90-
throw new Error(
91-
`Bundle with name "${bundleName}" already exists in "${functionsDir}"`
92-
);
101+
if (hasFilesOfType(files, 'functions')) {
102+
try {
103+
await mkdir(functionsTargetDir);
104+
} catch (err) {
105+
log(err);
106+
throw new Error(
107+
`Bundle with name "${bundleName}" already exists in "${functionsDir}"`
108+
);
109+
}
93110
}
94-
try {
95-
await mkdir(assetsTargetDir);
96-
} catch (err) {
97-
console.error(err);
98-
throw new Error(
99-
`Bundle with name "${bundleName}" already exists in "${assetsDir}"`
100-
);
111+
112+
if (hasFilesOfType(files, 'assets')) {
113+
try {
114+
await mkdir(assetsTargetDir);
115+
} catch (err) {
116+
log(err);
117+
throw new Error(
118+
`Bundle with name "${bundleName}" already exists in "${assetsDir}"`
119+
);
120+
}
101121
}
102122
}
103123

0 commit comments

Comments
 (0)