UNPKG

9.48 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const cli_framework_1 = require("@ionic/cli-framework");
4const format_1 = require("@ionic/cli-framework/utils/format");
5const string_1 = require("@ionic/cli-framework/utils/string");
6const path = require("path");
7const constants_1 = require("../constants");
8const color_1 = require("../lib/color");
9const command_1 = require("../lib/command");
10const errors_1 = require("../lib/errors");
11const project_1 = require("../lib/project");
12class InitCommand extends command_1.Command {
13 async getMetadata() {
14 return {
15 name: 'init',
16 type: 'global',
17 summary: 'Initialize existing projects with Ionic',
18 description: `
19This command will initialize an Ionic app within the current directory. Usually, this means an ${color_1.input(constants_1.PROJECT_FILE)} file is created. If used within a multi-app project, the app is initialized in the root ${color_1.input(constants_1.PROJECT_FILE)}.
20
21${color_1.input('ionic init')} will prompt for a project name and then proceed to determine the type of your project. You can specify the ${color_1.input('name')} argument and ${color_1.input('--type')} option to provide these values via command-line.
22
23If the ${color_1.input('--multi-app')} flag is specified, this command will initialize your project as a multi-app project, allowing for apps within monorepos and unconventional repository structures. See the multi-app docs[^multi-app-docs] for details. Once a multi-app project is initialized, you can run ${color_1.input('ionic init')} again within apps in your project to initialize them.
24 `,
25 exampleCommands: [
26 '',
27 '"My App"',
28 '"My App" --type=angular',
29 '--multi-app',
30 ],
31 inputs: [
32 {
33 name: 'name',
34 summary: `The name of your project (e.g. ${color_1.input('myApp')}, ${color_1.input('"My App"')})`,
35 },
36 ],
37 options: [
38 {
39 name: 'type',
40 summary: `Type of project (e.g. ${constants_1.MODERN_PROJECT_TYPES.map(type => color_1.input(type)).join(', ')})`,
41 },
42 {
43 name: 'force',
44 summary: 'Initialize even if a project already exists',
45 type: Boolean,
46 aliases: ['f'],
47 default: false,
48 },
49 {
50 name: 'multi-app',
51 summary: 'Initialize a multi-app project',
52 type: Boolean,
53 default: false,
54 },
55 {
56 name: 'project-id',
57 summary: 'Specify a slug for your app',
58 groups: ["advanced" /* ADVANCED */],
59 spec: { value: 'slug' },
60 hint: color_1.weak('[multi-app]'),
61 },
62 {
63 name: 'default',
64 summary: 'Mark the initialized app as the default project',
65 type: Boolean,
66 groups: ["advanced" /* ADVANCED */],
67 hint: color_1.weak('[multi-app]'),
68 },
69 ],
70 groups: ["beta" /* BETA */],
71 footnotes: [
72 {
73 id: 'multi-app-docs',
74 url: 'https://ionicframework.com/docs/cli/configuration#multi-app-projects',
75 shortUrl: 'https://ion.link/multi-app-docs',
76 },
77 ],
78 };
79 }
80 async preRun(inputs, options) {
81 const force = options['force'] ? true : false;
82 if (this.project && !force) {
83 // TODO: check for existing project config in multi-app
84 if (this.project.details.context === 'app' || (this.project.details.context === 'multiapp' && options['multi-app'])) {
85 throw new errors_1.FatalException(`Existing Ionic project file found: ${color_1.strong(format_1.prettyPath(this.project.filePath))}\n` +
86 `You can re-initialize your project using the ${color_1.input('--force')} option.`);
87 }
88 }
89 if (!options['multi-app']) {
90 if (!inputs[0]) {
91 const name = await this.env.prompt({
92 type: 'input',
93 name: 'name',
94 message: 'Project name:',
95 validate: v => cli_framework_1.validators.required(v),
96 });
97 inputs[0] = name;
98 }
99 if (!options['type']) {
100 const details = new project_1.ProjectDetails({ rootDirectory: this.env.ctx.execPath, e: this.env });
101 options['type'] = await details.getTypeFromDetection();
102 }
103 if (!options['type']) {
104 if (this.env.flags.interactive) {
105 this.env.log.warn(`Could not determine project type.\n` +
106 `Please choose a project type from the list.`);
107 this.env.log.nl();
108 }
109 const type = await this.env.prompt({
110 type: 'list',
111 name: 'type',
112 message: 'Project type:',
113 choices: constants_1.MODERN_PROJECT_TYPES.map(t => ({
114 name: `${project_1.prettyProjectName(t)} (${color_1.input(t)})`,
115 value: t,
116 })),
117 });
118 options['type'] = type;
119 }
120 }
121 }
122 async run(inputs, options) {
123 if (options['multi-app']) {
124 await this.initializeMultiProject(inputs, options);
125 }
126 else {
127 await this.initializeApp(inputs, options);
128 }
129 this.env.log.ok('Your Ionic project has been initialized!');
130 }
131 async initializeMultiProject(inputs, options) {
132 const configPath = this.getProjectFilePath();
133 const config = new project_1.MultiProjectConfig(configPath);
134 config.c = { projects: {} };
135 }
136 async initializeApp(inputs, options) {
137 const name = inputs[0] ? inputs[0].trim() : '';
138 const type = options['type'] ? String(options['type']) : undefined;
139 const projectId = options['project-id'] ? String(options['project-id']) : string_1.slugify(name); // TODO validate --project-id
140 if (!name) {
141 throw new errors_1.FatalException(`Project name not specified.\n` +
142 `Please specify ${color_1.input('name')}, the first argument of ${color_1.input('ionic init')}. See ${color_1.input('ionic init --help')} for details.`);
143 }
144 if (!type) {
145 throw new errors_1.FatalException(`Could not determine project type.\n` +
146 `Please specify ${color_1.input('--type')}. See ${color_1.input('ionic init --help')} for details.`);
147 }
148 let project;
149 if (this.project && this.project.details.context === 'multiapp') {
150 const configPath = path.resolve(this.project.rootDirectory, constants_1.PROJECT_FILE);
151 const projectRoot = path.relative(this.project.rootDirectory, this.env.ctx.execPath);
152 const config = new project_1.MultiProjectConfig(configPath);
153 if (!projectRoot) {
154 if (this.env.flags.interactive) {
155 this.env.log.warn(`About to initialize app in the root directory of your multi-app project.\n` +
156 `Please confirm that you want your app initialized in the root of your multi-app project. If this wasn't intended, please ${color_1.input('cd')} into the appropriate directory and run ${color_1.input('ionic init')} again.\n`);
157 }
158 const confirm = await this.env.prompt({
159 type: 'confirm',
160 message: 'Continue?',
161 default: false,
162 });
163 if (!confirm) {
164 throw new errors_1.FatalException(`Not initializing app in root directory.`);
165 }
166 }
167 const defaultProject = config.get('defaultProject');
168 if (!defaultProject && typeof options['default'] !== 'boolean') {
169 const confirm = await this.env.prompt({
170 type: 'confirm',
171 message: `Would you like to make this app the default project?`,
172 default: true,
173 });
174 if (confirm) {
175 options['default'] = true;
176 }
177 }
178 if (options['default']) {
179 config.set('defaultProject', projectId);
180 }
181 project = await project_1.createProjectFromDetails({ context: 'multiapp', configPath, id: projectId, type, errors: [] }, this.env);
182 project.config.set('root', projectRoot);
183 }
184 else {
185 const configPath = this.getProjectFilePath();
186 project = await project_1.createProjectFromDetails({ context: 'app', configPath, type, errors: [] }, this.env);
187 }
188 project.config.set('name', name);
189 project.config.set('type', type);
190 }
191 getProjectFilePath() {
192 return path.resolve(this.env.ctx.execPath, constants_1.PROJECT_FILE);
193 }
194}
195exports.InitCommand = InitCommand;