Skip to content

Commit 634679a

Browse files
committed
chore(cli): rebasing head
1 parent b7f278b commit 634679a

File tree

5 files changed

+233
-240
lines changed

5 files changed

+233
-240
lines changed

src/SDK/Language/CLI.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ public function getFiles(): array
177177
'destination' => 'lib/commands/init.js',
178178
'template' => 'cli/lib/commands/init.js.twig',
179179
],
180+
[
181+
'scope' => 'default',
182+
'destination' => 'lib/commands/create.js',
183+
'template' => 'cli/lib/commands/create.js.twig',
184+
],
180185
[
181186
'scope' => 'default',
182187
'destination' => 'lib/commands/pull.js',

templates/cli/index.js.twig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const { commandDescriptions, cliConfig } = require("./lib/parser");
1212
const { client } = require("./lib/commands/generic");
1313
{% if sdk.test != "true" %}
1414
const { login, logout } = require("./lib/commands/generic");
15+
const { create } = require("./lib/commands/create");
1516
const { init } = require("./lib/commands/init");
1617
const { pull } = require("./lib/commands/pull");
1718
const { push } = require("./lib/commands/push");
@@ -38,6 +39,7 @@ program
3839
.showSuggestionAfterError()
3940
{% if sdk.test != "true" %}
4041
.addCommand(login)
42+
.addCommand(create)
4143
.addCommand(init)
4244
.addCommand(pull)
4345
.addCommand(push)
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
const fs = require("fs");
2+
const path = require("path");
3+
const childProcess = require('child_process');
4+
const { Command } = require("commander");
5+
const inquirer = require("inquirer");
6+
const { storageCreateBucket } = require("./storage");
7+
const { messagingCreateTopic } = require("./messaging");
8+
const { functionsCreate } = require("./functions");
9+
const { databasesCreateCollection } = require("./databases");
10+
const ID = require("../id");
11+
const { localConfig } = require("../config");
12+
const {
13+
questionsCreateFunction,
14+
questionsCreateBucket,
15+
questionsCreateMessagingTopic,
16+
questionsCreateCollection
17+
} = require("../questions");
18+
const { success, error, actionRunner, commandDescriptions } = require("../parser");
19+
20+
const create = new Command("create")
21+
.description(commandDescriptions['create'])
22+
.configureHelp({
23+
helpWidth: process.stdout.columns || 80
24+
})
25+
.action(actionRunner(async (_options, command) => {
26+
command.help();
27+
}));
28+
29+
30+
const createBucket = async () => {
31+
let response = {}
32+
const answers = await inquirer.prompt(questionsCreateBucket)
33+
if (!answers.bucket || !answers.id || !answers.fileSecurity) process.exit(1)
34+
35+
try {
36+
response = await storageCreateBucket({
37+
bucketId: answers.id,
38+
name: answers.bucket,
39+
fileSecurity: answers.fileSecurity.toLowerCase() === 'yes',
40+
enabled: true,
41+
parseOutput: false
42+
})
43+
44+
localConfig.addBucket(response);
45+
success();
46+
} catch (e) {
47+
error(e.getMessage ?? 'Unknown error occurred. Please try again');
48+
}
49+
};
50+
51+
const createCollection = async () => {
52+
let response = {}
53+
const answers = await inquirer.prompt(questionsCreateCollection)
54+
if (!answers.database || !answers.collection || !answers.id || !answers.documentSecurity) process.exit(1)
55+
56+
try {
57+
response = await databasesCreateCollection({
58+
databaseId: answers.database,
59+
collectionId: answers.id,
60+
name: answers.collection,
61+
documentSecurity: answers.documentSecurity.toLowerCase() === 'yes',
62+
enabled: true,
63+
parseOutput: false
64+
})
65+
66+
localConfig.addCollection(response);
67+
success();
68+
} catch (e) {
69+
error(e.getMessage ?? 'Unknown error occurred. Please try again');
70+
}
71+
};
72+
73+
const createTopic = async () => {
74+
let response = {}
75+
const answers = await inquirer.prompt(questionsCreateMessagingTopic)
76+
if (!answers.topic || !answers.id) process.exit(1)
77+
78+
try {
79+
response = await messagingCreateTopic({
80+
topicId: answers.id,
81+
name: answers.topic,
82+
parseOutput: false
83+
})
84+
85+
localConfig.addMessagingTopic(response);
86+
success();
87+
} catch (e) {
88+
error(e.getMessage ?? 'Unknown error occurred. Please try again');
89+
}
90+
};
91+
92+
const createFunction = async () => {
93+
// TODO: Add CI/CD support (ID, name, runtime)
94+
const answers = await inquirer.prompt(questionsCreateFunction)
95+
const functionFolder = path.join(process.cwd(), 'functions');
96+
97+
if (!fs.existsSync(functionFolder)) {
98+
fs.mkdirSync(functionFolder, {
99+
recursive: true
100+
});
101+
}
102+
103+
const functionId = answers.id === 'unique()' ? ID.unique() : answers.id;
104+
const functionDir = path.join(functionFolder, functionId);
105+
106+
if (fs.existsSync(functionDir)) {
107+
throw new Error(`( ${functionId} ) already exists in the current directory. Please choose another name.`);
108+
}
109+
110+
if (!answers.runtime.entrypoint) {
111+
log(`Entrypoint for this runtime not found. You will be asked to configure entrypoint when you first push the function.`);
112+
}
113+
114+
if (!answers.runtime.commands) {
115+
log(`Installation command for this runtime not found. You will be asked to configure the install command when you first push the function.`);
116+
}
117+
118+
let response = await functionsCreate({
119+
functionId,
120+
name: answers.name,
121+
runtime: answers.runtime.id,
122+
entrypoint: answers.runtime.entrypoint || '',
123+
commands: answers.runtime.commands || '',
124+
parseOutput: false
125+
})
126+
127+
fs.mkdirSync(functionDir, "777");
128+
129+
let gitInitCommands = "git clone -b v3 --single-branch --depth 1 --sparse https://github.com/{{ sdk.gitUserName }}/functions-starter ."; // depth prevents fetching older commits reducing the amount fetched
130+
131+
let gitPullCommands = `git sparse-checkout add ${answers.runtime.id}`;
132+
133+
/* Force use CMD as powershell does not support && */
134+
if (process.platform === 'win32') {
135+
gitInitCommands = 'cmd /c "' + gitInitCommands + '"';
136+
gitPullCommands = 'cmd /c "' + gitPullCommands + '"';
137+
}
138+
139+
/* Execute the child process but do not print any std output */
140+
try {
141+
childProcess.execSync(gitInitCommands, { stdio: 'pipe', cwd: functionDir });
142+
childProcess.execSync(gitPullCommands, { stdio: 'pipe', cwd: functionDir });
143+
} catch (error) {
144+
/* Specialised errors with recommended actions to take */
145+
if (error.message.includes('error: unknown option')) {
146+
throw new Error(`${error.message} \n\nSuggestion: Try updating your git to the latest version, then trying to run this command again.`)
147+
} else if (error.message.includes('is not recognized as an internal or external command,') || error.message.includes('command not found')) {
148+
throw new Error(`${error.message} \n\nSuggestion: It appears that git is not installed, try installing git then trying to run this command again.`)
149+
} else {
150+
throw error;
151+
}
152+
}
153+
154+
fs.rmSync(path.join(functionDir, ".git"), { recursive: true });
155+
const copyRecursiveSync = (src, dest) => {
156+
let exists = fs.existsSync(src);
157+
let stats = exists && fs.statSync(src);
158+
let isDirectory = exists && stats.isDirectory();
159+
if (isDirectory) {
160+
if (!fs.existsSync(dest)) {
161+
fs.mkdirSync(dest);
162+
}
163+
164+
fs.readdirSync(src).forEach(function (childItemName) {
165+
copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
166+
});
167+
} else {
168+
fs.copyFileSync(src, dest);
169+
}
170+
};
171+
copyRecursiveSync(path.join(functionDir, answers.runtime.id), functionDir);
172+
173+
fs.rmSync(`${functionDir}/${answers.runtime.id}`, { recursive: true, force: true });
174+
175+
const readmePath = path.join(process.cwd(), 'functions', functionId, 'README.md');
176+
const readmeFile = fs.readFileSync(readmePath).toString();
177+
const newReadmeFile = readmeFile.split('\n');
178+
newReadmeFile[0] = `# ${answers.name}`;
179+
newReadmeFile.splice(1, 2);
180+
fs.writeFileSync(readmePath, newReadmeFile.join('\n'));
181+
182+
let data = {
183+
$id: response['$id'],
184+
name: response.name,
185+
runtime: response.runtime,
186+
execute: response.execute,
187+
events: response.events,
188+
schedule: response.schedule,
189+
timeout: response.timeout,
190+
enabled: response.enabled,
191+
logging: response.logging,
192+
entrypoint: response.entrypoint,
193+
commands: response.commands,
194+
ignore: answers.runtime.ignore || null,
195+
path: `functions/${functionId}`,
196+
};
197+
198+
localConfig.addFunction(data);
199+
success();
200+
}
201+
202+
create
203+
.command("function")
204+
.description("Create a new {{ spec.title|caseUcfirst }} function")
205+
.action(actionRunner(createFunction));
206+
207+
create
208+
.command("bucket")
209+
.description("Create a new {{ spec.title|caseUcfirst }} bucket")
210+
.action(actionRunner(createBucket));
211+
212+
create
213+
.command("collection")
214+
.description("Create a new {{ spec.title|caseUcfirst }} collection")
215+
.action(actionRunner(createCollection));
216+
217+
create
218+
.command("topic")
219+
.description("Create a new {{ spec.title|caseUcfirst }} topic")
220+
.action(actionRunner(createTopic));
221+
222+
module.exports = {
223+
create,
224+
};

0 commit comments

Comments
 (0)