Skip to content

Commit ea26181

Browse files
matthewkremerimhoffd
authored andcommitted
feat(start): add conference and my-first-app starter templates for angular (#3978)
1 parent 4b2f821 commit ea26181

File tree

3 files changed

+165
-110
lines changed

3 files changed

+165
-110
lines changed

packages/ionic/src/commands/start.ts

Lines changed: 94 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -136,58 +136,12 @@ Use the ${input('--type')} option to start projects using older versions of Ioni
136136
async preRun(inputs: CommandLineInputs, options: CommandLineOptions): Promise<void> {
137137
const { promptToLogin } = await import('../lib/session');
138138

139-
const cloned = isValidURL(inputs[1]);
140-
141139
verifyOptions(options, this.env);
142140

143-
if (cloned) {
144-
if (!options['git']) {
145-
this.env.log.warn(`The ${input('--no-git')} option has no effect when cloning apps. Git must be used.`);
146-
}
147-
148-
options['git'] = true;
149-
}
150-
151-
if (this.project && this.project.details.context === 'app') {
152-
const confirm = await this.env.prompt({
153-
type: 'confirm',
154-
name: 'confirm',
155-
message: 'You are already in an Ionic project directory. Do you really want to start another project here?',
156-
default: false,
157-
});
158-
159-
if (!confirm) {
160-
this.env.log.info('Not starting project within existing project.');
161-
throw new FatalException();
162-
}
163-
}
164-
141+
const appflowId = options['id'] ? String(options['id']) : undefined;
165142
// TODO: currently defaults to angular as the project type if a type is not provided
166143
// we might want to make them select a type instead
167144
const projectType = options['type'] ? String(options['type']) : 'angular';
168-
const appflowId = options['id'] ? String(options['id']) : undefined;
169-
170-
await this.validateProjectType(projectType);
171-
172-
if (options['v1'] || options['v2']) {
173-
throw new FatalException(
174-
`The ${input('--v1')} and ${input('--v2')} flags have been removed.\n` +
175-
`Use the ${input('--type')} option. (see ${input('ionic start --help')})`
176-
);
177-
}
178-
179-
if (options['app-name']) {
180-
this.env.log.warn(`The ${input('--app-name')} option has been removed. Use the ${input('name')} argument with double quotes: e.g. ${input('ionic start "My App"')}`);
181-
}
182-
183-
if (options['display-name']) {
184-
this.env.log.warn(`The ${input('--display-name')} option has been removed. Use the ${input('name')} argument with double quotes: e.g. ${input('ionic start "My App"')}`);
185-
}
186-
187-
if (options['bundle-id']) {
188-
this.env.log.warn(`The ${input('--bundle-id')} option has been deprecated. Please use ${input('--package-id')}.`);
189-
options['package-id'] = options['bundle-id'];
190-
}
191145

192146
if (appflowId) {
193147
if (!this.env.session.isLoggedIn()) {
@@ -228,6 +182,92 @@ Use the ${input('--type')} option to start projects using older versions of Ioni
228182
}
229183
}
230184

185+
if (!inputs[1]) {
186+
if (this.env.flags.interactive) {
187+
this.env.log.nl();
188+
this.env.log.msg(
189+
`${strong(`Let's pick the perfect starter template! ${emoji('💪', '')}`)}\n` +
190+
`Starter templates are ready-to-go Ionic apps that come packed with everything you need to build your app. To bypass this prompt next time, supply ${input('template')}, the second argument to ${input('ionic start')}.\n\n`
191+
);
192+
}
193+
194+
const template = await this.env.prompt({
195+
type: 'list',
196+
name: 'template',
197+
message: 'Starter template:',
198+
choices: () => {
199+
const starterTemplateList = STARTER_TEMPLATES.filter(st => st.projectType === projectType);
200+
const cols = columnar(starterTemplateList.map(({ name, description }) => [input(name), description || '']), {}).split('\n');
201+
202+
if (starterTemplateList.length === 0) {
203+
throw new FatalException(`No starter templates found for project type: ${input(projectType)}.`);
204+
}
205+
206+
return starterTemplateList.map((starterTemplate, i) => {
207+
return {
208+
name: cols[i],
209+
short: starterTemplate.name,
210+
value: starterTemplate.name,
211+
};
212+
});
213+
},
214+
});
215+
216+
inputs[1] = template;
217+
}
218+
219+
const starterTemplate = STARTER_TEMPLATES.find(t => t.name === inputs[1]);
220+
221+
if (starterTemplate && starterTemplate.type === 'repo') {
222+
inputs[1] = starterTemplate.repo;
223+
}
224+
225+
const cloned = isValidURL(inputs[1]);
226+
227+
if (this.project && this.project.details.context === 'app') {
228+
const confirm = await this.env.prompt({
229+
type: 'confirm',
230+
name: 'confirm',
231+
message: 'You are already in an Ionic project directory. Do you really want to start another project here?',
232+
default: false,
233+
});
234+
235+
if (!confirm) {
236+
this.env.log.info('Not starting project within existing project.');
237+
throw new FatalException();
238+
}
239+
}
240+
241+
await this.validateProjectType(projectType);
242+
243+
if (cloned) {
244+
if (!options['git']) {
245+
this.env.log.warn(`The ${input('--no-git')} option has no effect when cloning apps. Git must be used.`);
246+
}
247+
248+
options['git'] = true;
249+
}
250+
251+
if (options['v1'] || options['v2']) {
252+
throw new FatalException(
253+
`The ${input('--v1')} and ${input('--v2')} flags have been removed.\n` +
254+
`Use the ${input('--type')} option. (see ${input('ionic start --help')})`
255+
);
256+
}
257+
258+
if (options['app-name']) {
259+
this.env.log.warn(`The ${input('--app-name')} option has been removed. Use the ${input('name')} argument with double quotes: e.g. ${input('ionic start "My App"')}`);
260+
}
261+
262+
if (options['display-name']) {
263+
this.env.log.warn(`The ${input('--display-name')} option has been removed. Use the ${input('name')} argument with double quotes: e.g. ${input('ionic start "My App"')}`);
264+
}
265+
266+
if (options['bundle-id']) {
267+
this.env.log.warn(`The ${input('--bundle-id')} option has been deprecated. Please use ${input('--package-id')}.`);
268+
options['package-id'] = options['bundle-id'];
269+
}
270+
231271
let projectId = options['project-id'] ? String(options['project-id']) : undefined;
232272

233273
if (projectId) {
@@ -245,48 +285,14 @@ Use the ${input('--type')} option to start projects using older versions of Ioni
245285

246286
if (cloned) {
247287
this.schema = {
248-
cloned,
288+
cloned: true,
249289
url: inputs[1],
250290
projectId,
251291
projectDir,
252292
};
253293
} else {
254-
if (!inputs[1]) {
255-
if (this.env.flags.interactive) {
256-
this.env.log.nl();
257-
this.env.log.msg(
258-
`${strong(`Let's pick the perfect starter template! ${emoji('💪', '')}`)}\n` +
259-
`Starter templates are ready-to-go Ionic apps that come packed with everything you need to build your app. To bypass this prompt next time, supply ${input('template')}, the second argument to ${input('ionic start')}.\n\n`
260-
);
261-
}
262-
263-
const template = await this.env.prompt({
264-
type: 'list',
265-
name: 'template',
266-
message: 'Starter template:',
267-
choices: () => {
268-
const starterTemplateList = STARTER_TEMPLATES.filter(st => st.type === projectType);
269-
const cols = columnar(starterTemplateList.map(({ name, description }) => [input(name), description || '']), {}).split('\n');
270-
271-
if (starterTemplateList.length === 0) {
272-
throw new FatalException(`No starter templates found for project type: ${input(projectType)}.`);
273-
}
274-
275-
return starterTemplateList.map((starterTemplate, i) => {
276-
return {
277-
name: cols[i],
278-
short: starterTemplate.name,
279-
value: starterTemplate.name,
280-
};
281-
});
282-
},
283-
});
284-
285-
inputs[1] = template;
286-
}
287-
288294
this.schema = {
289-
cloned,
295+
cloned: false,
290296
name: inputs[0],
291297
type: projectType as ProjectType,
292298
template: inputs[1],
@@ -303,7 +309,7 @@ Use the ${input('--type')} option to start projects using older versions of Ioni
303309
const { getTopLevel, isGitInstalled } = await import('../lib/git');
304310

305311
if (!this.schema) {
306-
throw new FatalException(`Invalid information: cannot start app.`);
312+
throw new FatalException(`Invalid start schema: cannot start app.`);
307313
}
308314

309315
const { projectId, projectDir, packageId, appflowId } = this.schema;
@@ -489,9 +495,9 @@ Use the ${input('--type')} option to start projects using older versions of Ioni
489495
}
490496

491497
async findStarterTemplate(template: string, type: string, tag: string): Promise<ResolvedStarterTemplate> {
492-
const starterTemplate = STARTER_TEMPLATES.find(t => t.type === type && t.name === template);
498+
const starterTemplate = STARTER_TEMPLATES.find(t => t.projectType === type && t.name === template);
493499

494-
if (starterTemplate) {
500+
if (starterTemplate && starterTemplate.type === 'managed') {
495501
return {
496502
...starterTemplate,
497503
archive: `${STARTER_BASE_URL}/${tag === 'latest' ? '' : `${tag}/`}${starterTemplate.id}.tar.gz`,
@@ -508,7 +514,8 @@ Use the ${input('--type')} option to start projects using older versions of Ioni
508514
tasks.end();
509515

510516
return {
511-
...starter,
517+
name: starter.name,
518+
projectType: starter.type,
512519
archive: `${STARTER_BASE_URL}/${tag === 'latest' ? '' : `${tag}/`}${starter.id}.tar.gz`,
513520
};
514521
} else {

packages/ionic/src/definitions.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -821,14 +821,25 @@ export interface StarterList {
821821
}[];
822822
}
823823

824-
export interface StarterTemplate {
824+
export interface BaseStarterTemplate {
825825
name: string;
826-
type: ProjectType;
827-
id: string;
826+
projectType: ProjectType;
828827
description?: string;
829828
}
830829

831-
export interface ResolvedStarterTemplate extends StarterTemplate {
830+
export interface RepoStarterTemplate extends BaseStarterTemplate {
831+
type: 'repo';
832+
repo: string;
833+
}
834+
835+
export interface ManagedStarterTemplate extends BaseStarterTemplate {
836+
type: 'managed';
837+
id: string;
838+
}
839+
840+
export type StarterTemplate = RepoStarterTemplate | ManagedStarterTemplate;
841+
842+
export interface ResolvedStarterTemplate extends BaseStarterTemplate {
832843
archive: string;
833844
}
834845

0 commit comments

Comments
 (0)