1 | const fs = require('fs-extra');
|
2 | const path = require('path');
|
3 | const R = require('ramda');
|
4 |
|
5 | const SkillInfrastructureController = require('@src/controllers/skill-infrastructure-controller');
|
6 | const CliWarn = require('@src/exceptions/cli-warn');
|
7 | const AskResources = require('@src/model/resources-config/ask-resources');
|
8 | const AskStates = require('@src/model/resources-config/ask-states');
|
9 | const ResourcesConfig = require('@src/model/resources-config');
|
10 | const stringUtils = require('@src/utils/string-utils');
|
11 | const CONSTANTS = require('@src/utils/constants');
|
12 | const Messenger = require('@src/view/messenger');
|
13 |
|
14 | const ui = require('./ui');
|
15 |
|
16 | module.exports = {
|
17 | preInitCheck,
|
18 | getSkillIdUserInput,
|
19 | getSkillMetadataUserInput,
|
20 | getSkillCodeUserInput,
|
21 | getSkillInfraUserInput,
|
22 | previewAndWriteAskResources,
|
23 | bootstrapSkillInfra
|
24 | };
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | function preInitCheck(rootPath, profile, callback) {
|
33 | ui.showInitInstruction(profile);
|
34 | _attemptGetAskResources(rootPath, (attemptErr) => {
|
35 | callback(attemptErr);
|
36 | });
|
37 | }
|
38 |
|
39 | function _attemptGetAskResources(rootPath, callback) {
|
40 | const askResourcesPath = path.join(rootPath, CONSTANTS.FILE_PATH.ASK_RESOURCES_JSON_CONFIG);
|
41 | if (fs.existsSync(askResourcesPath)) {
|
42 | ui.confirmOverwrite((confirmErr, isConfirmed) => {
|
43 | if (confirmErr) {
|
44 | return callback(confirmErr);
|
45 | }
|
46 | if (!isConfirmed) {
|
47 | return callback(
|
48 | new CliWarn(`Please modify the existing ${CONSTANTS.FILE_PATH.ASK_RESOURCES_JSON_CONFIG} file or choose to overwrite.`)
|
49 | );
|
50 | }
|
51 | callback();
|
52 | });
|
53 | } else {
|
54 | process.nextTick(() => {
|
55 | callback();
|
56 | });
|
57 | }
|
58 | }
|
59 |
|
60 |
|
61 |
|
62 |
|
63 |
|
64 | function getSkillIdUserInput(callback) {
|
65 | ui.getSkillId((skillIdErr, skillId) => {
|
66 | callback(skillIdErr, !skillIdErr ? skillId : null);
|
67 |
|
68 | });
|
69 | }
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | function getSkillMetadataUserInput(callback) {
|
76 | ui.getSkillMetaSrc((skillMetaErr, skillMetaSrc) => {
|
77 | callback(skillMetaErr, !skillMetaErr ? { src: skillMetaSrc } : null);
|
78 | });
|
79 | }
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 | function getSkillCodeUserInput(callback) {
|
86 | ui.getCodeSrcForRegion(CONSTANTS.ALEXA.REGION.DEFAULT, (defaultRegionErr, defaultSrc) => {
|
87 | if (defaultRegionErr) {
|
88 | return callback(defaultRegionErr);
|
89 | }
|
90 | if (defaultSrc === '') {
|
91 | return callback();
|
92 | }
|
93 | const skillCode = {};
|
94 | skillCode[CONSTANTS.ALEXA.REGION.DEFAULT] = { src: defaultSrc };
|
95 | callback(null, skillCode);
|
96 | });
|
97 | }
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 | function getSkillInfraUserInput(callback) {
|
104 | ui.getSkillInfra((deployerErr, infraSettings) => {
|
105 | if (deployerErr) {
|
106 | return callback(deployerErr);
|
107 | }
|
108 | const skillInfra = {};
|
109 | skillInfra.type = infraSettings.isUsingCfn ? '@ask-cli/cfn-deployer' : '@ask-cli/lambda-deployer';
|
110 | skillInfra.userConfig = {
|
111 | runtime: infraSettings.runtime,
|
112 | handler: infraSettings.handler
|
113 | };
|
114 | callback(null, skillInfra);
|
115 | });
|
116 | }
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 | function previewAndWriteAskResources(rootPath, userInput, profile, callback) {
|
126 | const { askResources, askStates } = _assembleAskResources(userInput, profile);
|
127 | ui.showPreviewAndConfirm(rootPath, { askResources, askStates }, (confirmErr, isConfirmed) => {
|
128 | if (confirmErr) {
|
129 | return callback(confirmErr);
|
130 | }
|
131 | if (!isConfirmed) {
|
132 | return callback(new CliWarn('Project init aborted.'));
|
133 | }
|
134 | try {
|
135 | const askResourcesFilePath = path.join(rootPath, CONSTANTS.FILE_PATH.ASK_RESOURCES_JSON_CONFIG);
|
136 | const askHiddenFolder = path.join(rootPath, CONSTANTS.FILE_PATH.HIDDEN_ASK_FOLDER);
|
137 | const askStatesFilePath = path.join(askHiddenFolder, CONSTANTS.FILE_PATH.ASK_STATES_JSON_CONFIG);
|
138 | fs.removeSync(askResourcesFilePath);
|
139 | AskResources.withContent(askResourcesFilePath, askResources);
|
140 | fs.removeSync(askHiddenFolder);
|
141 | AskStates.withContent(askStatesFilePath, askStates);
|
142 | } catch (writeErr) {
|
143 | return callback(writeErr);
|
144 | }
|
145 | callback();
|
146 | });
|
147 | }
|
148 |
|
149 | function _assembleAskResources(userInput, profile) {
|
150 | const askResourcesJson = R.clone(AskResources.BASE);
|
151 | const askStatesJson = R.clone(AskStates.BASE);
|
152 | const askProfileResources = { skillMetadata: userInput.skillMeta };
|
153 | const askProfileStates = { skillId: userInput.skillId };
|
154 | if (userInput.skillCode) {
|
155 | askProfileResources.code = userInput.skillCode;
|
156 | }
|
157 | if (userInput.skillInfra) {
|
158 | askProfileResources.skillInfrastructure = userInput.skillInfra;
|
159 | askProfileStates.skillInfrastructure = {
|
160 | [userInput.skillInfra.type]: {
|
161 | deployState: {}
|
162 | }
|
163 | };
|
164 | }
|
165 | return {
|
166 | askResources: R.set(R.lensPath(['profiles', profile]), askProfileResources, askResourcesJson),
|
167 | askStates: R.set(R.lensPath(['profiles', profile]), askProfileStates, askStatesJson)
|
168 | };
|
169 | }
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
176 |
|
177 |
|
178 | function bootstrapSkillInfra(rootPath, profile, doDebug, callback) {
|
179 | const askResourcesFilePath = path.join(rootPath, CONSTANTS.FILE_PATH.ASK_RESOURCES_JSON_CONFIG);
|
180 | new ResourcesConfig(askResourcesFilePath);
|
181 | const deployerType = ResourcesConfig.getInstance().getSkillInfraType(profile);
|
182 | if (!stringUtils.isNonBlankString(deployerType)) {
|
183 | return process.nextTick(() => {
|
184 | callback();
|
185 | });
|
186 | }
|
187 |
|
188 | const ddFolderPath = deployerType.startsWith('@ask-cli/') ? deployerType.replace('@ask-cli/', '') : deployerType;
|
189 | const deployerPath = path.join(rootPath, CONSTANTS.FILE_PATH.SKILL_INFRASTRUCTURE.INFRASTRUCTURE, ddFolderPath);
|
190 | fs.ensureDirSync(deployerPath);
|
191 | const skillInfraController = new SkillInfrastructureController({ profile, doDebug });
|
192 | skillInfraController.bootstrapInfrastructures(deployerPath, (bootstrapErr) => {
|
193 | if (bootstrapErr) {
|
194 | return callback(bootstrapErr);
|
195 | }
|
196 | ResourcesConfig.getInstance().write();
|
197 | Messenger.getInstance().info(`Project bootstrap from deployer "${deployerType}" succeeded.`);
|
198 | callback();
|
199 | });
|
200 | }
|