Skip to content

Commit f470390

Browse files
authored
create-spectacle: Better check for overwrite (#1205)
* Better check for overwrite * Move fallbacks to initial values in prompts * Update comment * Add changeset * More consistent language
1 parent 3ea97dc commit f470390

File tree

2 files changed

+53
-25
lines changed

2 files changed

+53
-25
lines changed

.changeset/tricky-drinks-listen.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'create-spectacle': patch
3+
---
4+
5+
Better overwrite logic based on whether HTML file or directory will be created

packages/create-spectacle/src/cli.ts

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,11 @@ const main = async () => {
4646
let i = 0;
4747
let type = argv[ArgName.type] || argv['t'];
4848
let name = argv['_']?.[0];
49-
let lang = argv[ArgName.lang] || argv['l'] || 'en';
50-
let port = argv[ArgName.port] || argv['p'] || 3000;
49+
let lang = argv[ArgName.lang] || argv['l'];
50+
let port = argv[ArgName.port] || argv['p'];
5151

52-
const isTryingToOverwrite = Boolean(name) && !isFolderNameAvailable(name);
52+
const isTryingToOverwrite =
53+
Boolean(name) && !isOutputPathAvailable(name, type === 'onepage');
5354

5455
/**
5556
* If type/name not both provided via CLI flags, prompt for them.
@@ -58,6 +59,7 @@ const main = async () => {
5859
const hasName = Boolean(name);
5960
const hasLang = Boolean(lang);
6061
const hasPort = type === 'onepage' || Boolean(port); // onepage has no port
62+
6163
if (!(hasType && hasName && hasLang && hasPort) || isTryingToOverwrite) {
6264
try {
6365
const response = await prompts(
@@ -72,14 +74,43 @@ const main = async () => {
7274
return val.trim().length > 0 ? true : 'Name is required';
7375
}
7476
},
77+
/**
78+
* Type of deck.
79+
* Needs to be before overwrite confirmation so we can determine if folder/file already exists.
80+
*/
81+
{
82+
type: 'select',
83+
name: ArgName.type as string,
84+
message: 'What type of deck do you want to create?',
85+
choices: DeckTypeOptions,
86+
initial: (() => {
87+
const ind = DeckTypeOptions.findIndex((o) => o.value === type);
88+
return ind > -1 ? ind : 0;
89+
})()
90+
},
7591
// If output directory already exists, prompt to overwrite
7692
{
77-
type: (val) => (isFolderNameAvailable(val) ? null : 'confirm'),
93+
type: (_, answers) =>
94+
isOutputPathAvailable(
95+
answers?.[ArgName.name],
96+
answers?.[ArgName.type] === 'onepage'
97+
)
98+
? null
99+
: 'confirm',
78100
name: ArgName.overwrite as string,
79-
message: (val) =>
80-
`Target directory ${formatProjectDirName(
81-
val
82-
)} already exists. Overwrite and continue?`
101+
message: (_, answers) => {
102+
const name = answers?.[ArgName.name];
103+
const type = answers?.[ArgName.type];
104+
if (type === 'onepage') {
105+
return `File ${formatProjectOutputPath(
106+
name
107+
)}.html already exists. Overwrite and continue?`;
108+
} else {
109+
return `Target directory ${formatProjectOutputPath(
110+
name
111+
)} already exists. Overwrite and continue?`;
112+
}
113+
}
83114
},
84115
// Check overwrite comes back false, we need to abort.
85116
{
@@ -91,23 +122,13 @@ const main = async () => {
91122
},
92123
name: 'overwriteAborter'
93124
},
94-
{
95-
type: 'select',
96-
name: ArgName.type as string,
97-
message: 'What type of deck do you want to create?',
98-
choices: DeckTypeOptions,
99-
initial: (() => {
100-
const ind = DeckTypeOptions.findIndex((o) => o.value === type);
101-
return ind > -1 ? ind : 0;
102-
})()
103-
},
104125
// Language prompt
105126
{
106127
type: 'text',
107128
name: ArgName.lang as string,
108129
message:
109130
'What is the language code for the generated HTML document?',
110-
initial: lang,
131+
initial: lang || 'en',
111132
validate: async (val) => {
112133
return val.trim().length > 0 ? true : 'Language code is required';
113134
}
@@ -118,7 +139,7 @@ const main = async () => {
118139
answers?.[ArgName.type] === 'onepage' ? null : 'text',
119140
name: ArgName.port as string,
120141
message: 'What port should the webpack dev server run on?',
121-
initial: port
142+
initial: port || '3000'
122143
}
123144
],
124145
{
@@ -149,7 +170,7 @@ const main = async () => {
149170
await sleep(750);
150171

151172
const fileOptions: FileOptions = {
152-
snakeCaseName: formatProjectDirName(name),
173+
snakeCaseName: formatProjectOutputPath(name),
153174
name,
154175
lang,
155176
port,
@@ -182,12 +203,14 @@ const main = async () => {
182203
);
183204
};
184205

185-
const formatProjectDirName = (name: string) =>
206+
const formatProjectOutputPath = (name: string) =>
186207
name.toLowerCase().replace(/([^a-z0-9]+)/gi, '-');
187208

188-
const isFolderNameAvailable = (name: string) => {
189-
const dir = path.join(cwd, formatProjectDirName(name));
190-
return !fs.existsSync(dir);
209+
const isOutputPathAvailable = (name: string, isHTMLFile = false) => {
210+
const outputPath = isHTMLFile
211+
? path.join(cwd, `${formatProjectOutputPath(name)}.html`)
212+
: path.join(cwd, formatProjectOutputPath(name));
213+
return !fs.existsSync(outputPath);
191214
};
192215

193216
main().catch((err) => {

0 commit comments

Comments
 (0)