Skip to content

Commit d4b2c33

Browse files
committed
refactor(cli): Function pull to create
1 parent e2e80e6 commit d4b2c33

File tree

3 files changed

+156
-161
lines changed

3 files changed

+156
-161
lines changed

templates/cli/lib/commands/create.js.twig

Lines changed: 116 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1+
const fs = require("fs");
2+
const path = require("path");
3+
const childProcess = require('child_process');
14
const { Command } = require("commander");
25
const inquirer = require("inquirer");
36
const { projectsCreate } = require("./projects");
47
const { storageCreateBucket } = require("./storage");
58
const { messagingCreateTopic } = require("./messaging");
9+
const { functionsCreate } = require("./functions");
610
const { databasesCreateCollection } = require("./databases");
711
const { sdkForConsole } = require("../sdks");
812
const { localConfig } = require("../config");
9-
const { questionsCreateProject, questionsCreateBucket, questionsCreateMessagingTopic, questionsCreateCollection } = require("../questions");
13+
const {
14+
questionsCreateProject,
15+
questionsCreateFunction,
16+
questionsCreateBucket,
17+
questionsCreateMessagingTopic,
18+
questionsCreateCollection
19+
} = require("../questions");
1020
const { success, error, actionRunner, commandDescriptions } = require("../parser");
1121

1222
const create = new Command("create")
@@ -97,10 +107,114 @@ const createTopic = async () => {
97107
};
98108

99109
const createFunction = async () => {
110+
// TODO: Add CI/CD support (ID, name, runtime)
111+
const answers = await inquirer.prompt(questionsCreateFunction)
112+
const functionFolder = path.join(process.cwd(), 'functions');
113+
114+
if (!fs.existsSync(functionFolder)) {
115+
fs.mkdirSync(functionFolder, {
116+
recursive: true
117+
});
118+
}
100119

101-
};
120+
const functionId = answers.id === 'unique()' ? ID.unique() : answers.id;
121+
const functionDir = path.join(functionFolder, functionId);
122+
123+
if (fs.existsSync(functionDir)) {
124+
throw new Error(`( ${functionId} ) already exists in the current directory. Please choose another name.`);
125+
}
126+
127+
if (!answers.runtime.entrypoint) {
128+
log(`Entrypoint for this runtime not found. You will be asked to configure entrypoint when you first push the function.`);
129+
}
130+
131+
if (!answers.runtime.commands) {
132+
log(`Installation command for this runtime not found. You will be asked to configure the install command when you first push the function.`);
133+
}
134+
135+
let response = await functionsCreate({
136+
functionId,
137+
name: answers.name,
138+
runtime: answers.runtime.id,
139+
entrypoint: answers.runtime.entrypoint || '',
140+
commands: answers.runtime.commands || '',
141+
parseOutput: false
142+
})
143+
144+
fs.mkdirSync(functionDir, "777");
145+
146+
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
147+
148+
let gitPullCommands = `git sparse-checkout add ${answers.runtime.id}`;
149+
150+
/* Force use CMD as powershell does not support && */
151+
if (process.platform === 'win32') {
152+
gitInitCommands = 'cmd /c "' + gitInitCommands + '"';
153+
gitPullCommands = 'cmd /c "' + gitPullCommands + '"';
154+
}
102155

156+
/* Execute the child process but do not print any std output */
157+
try {
158+
childProcess.execSync(gitInitCommands, { stdio: 'pipe', cwd: functionDir });
159+
childProcess.execSync(gitPullCommands, { stdio: 'pipe', cwd: functionDir });
160+
} catch (error) {
161+
/* Specialised errors with recommended actions to take */
162+
if (error.message.includes('error: unknown option')) {
163+
throw new Error(`${error.message} \n\nSuggestion: Try updating your git to the latest version, then trying to run this command again.`)
164+
} else if (error.message.includes('is not recognized as an internal or external command,') || error.message.includes('command not found')) {
165+
throw new Error(`${error.message} \n\nSuggestion: It appears that git is not installed, try installing git then trying to run this command again.`)
166+
} else {
167+
throw error;
168+
}
169+
}
103170

171+
fs.rmSync(path.join(functionDir, ".git"), { recursive: true });
172+
const copyRecursiveSync = (src, dest) => {
173+
let exists = fs.existsSync(src);
174+
let stats = exists && fs.statSync(src);
175+
let isDirectory = exists && stats.isDirectory();
176+
if (isDirectory) {
177+
if (!fs.existsSync(dest)) {
178+
fs.mkdirSync(dest);
179+
}
180+
181+
fs.readdirSync(src).forEach(function (childItemName) {
182+
copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
183+
});
184+
} else {
185+
fs.copyFileSync(src, dest);
186+
}
187+
};
188+
copyRecursiveSync(path.join(functionDir, answers.runtime.id), functionDir);
189+
190+
fs.rmSync(`${functionDir}/${answers.runtime.id}`, { recursive: true, force: true });
191+
192+
const readmePath = path.join(process.cwd(), 'functions', functionId, 'README.md');
193+
const readmeFile = fs.readFileSync(readmePath).toString();
194+
const newReadmeFile = readmeFile.split('\n');
195+
newReadmeFile[0] = `# ${answers.name}`;
196+
newReadmeFile.splice(1, 2);
197+
fs.writeFileSync(readmePath, newReadmeFile.join('\n'));
198+
199+
let data = {
200+
$id: response['$id'],
201+
name: response.name,
202+
runtime: response.runtime,
203+
execute: response.execute,
204+
events: response.events,
205+
schedule: response.schedule,
206+
timeout: response.timeout,
207+
enabled: response.enabled,
208+
logging: response.logging,
209+
entrypoint: response.entrypoint,
210+
commands: response.commands,
211+
ignore: answers.runtime.ignore || null,
212+
path: `functions/${functionId}`,
213+
};
214+
215+
localConfig.addFunction(data);
216+
success();
217+
}
104218

105219

106220

templates/cli/lib/commands/pull.js.twig

Lines changed: 1 addition & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
const fs = require("fs");
2-
const path = require("path");
3-
const childProcess = require('child_process');
41
const { Command } = require("commander");
52
const inquirer = require("inquirer");
63
const { teamsCreate, teamsList } = require("./teams");
74
const { projectsCreate } = require("./projects");
8-
const { functionsCreate } = require("./functions");
95
const { databasesGet, databasesListCollections, databasesList } = require("./databases");
106
const { storageListBuckets } = require("./storage");
117
const { sdkForConsole } = require("../sdks");
128
const { localConfig } = require("../config");
139
const ID = require("../id");
1410
const { paginate } = require("../paginate");
15-
const { questionsPullProject, questionsPullFunction, questionsPullCollection } = require("../questions");
11+
const { questionsPullProject, questionsPullCollection } = require("../questions");
1612
const { success, log, actionRunner, commandDescriptions } = require("../parser");
1713

1814
const pull = new Command("pull")
@@ -32,116 +28,6 @@ const pullProject = async () => {
3228
success();
3329
}
3430

35-
const pullFunction = async () => {
36-
// TODO: Add CI/CD support (ID, name, runtime)
37-
const answers = await inquirer.prompt(questionsPullFunction)
38-
const functionFolder = path.join(process.cwd(), 'functions');
39-
40-
if (!fs.existsSync(functionFolder)) {
41-
fs.mkdirSync(functionFolder, {
42-
recursive: true
43-
});
44-
}
45-
46-
const functionId = answers.id === 'unique()' ? ID.unique() : answers.id;
47-
const functionDir = path.join(functionFolder, functionId);
48-
49-
if (fs.existsSync(functionDir)) {
50-
throw new Error(`( ${functionId} ) already exists in the current directory. Please choose another name.`);
51-
}
52-
53-
if (!answers.runtime.entrypoint) {
54-
log(`Entrypoint for this runtime not found. You will be asked to configure entrypoint when you first push the function.`);
55-
}
56-
57-
if (!answers.runtime.commands) {
58-
log(`Installation command for this runtime not found. You will be asked to configure the install command when you first push the function.`);
59-
}
60-
61-
let response = await functionsCreate({
62-
functionId,
63-
name: answers.name,
64-
runtime: answers.runtime.id,
65-
entrypoint: answers.runtime.entrypoint || '',
66-
commands: answers.runtime.commands || '',
67-
parseOutput: false
68-
})
69-
70-
fs.mkdirSync(functionDir, "777");
71-
72-
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
73-
74-
let gitPullCommands = `git sparse-checkout add ${answers.runtime.id}`;
75-
76-
/* Force use CMD as powershell does not support && */
77-
if (process.platform === 'win32') {
78-
gitInitCommands = 'cmd /c "' + gitInitCommands + '"';
79-
gitPullCommands = 'cmd /c "' + gitPullCommands + '"';
80-
}
81-
82-
/* Execute the child process but do not print any std output */
83-
try {
84-
childProcess.execSync(gitInitCommands, { stdio: 'pipe', cwd: functionDir });
85-
childProcess.execSync(gitPullCommands, { stdio: 'pipe', cwd: functionDir });
86-
} catch (error) {
87-
/* Specialised errors with recommended actions to take */
88-
if (error.message.includes('error: unknown option')) {
89-
throw new Error(`${error.message} \n\nSuggestion: Try updating your git to the latest version, then trying to run this command again.`)
90-
} else if (error.message.includes('is not recognized as an internal or external command,') || error.message.includes('command not found')) {
91-
throw new Error(`${error.message} \n\nSuggestion: It appears that git is not installed, try installing git then trying to run this command again.`)
92-
} else {
93-
throw error;
94-
}
95-
}
96-
97-
fs.rmSync(path.join(functionDir, ".git"), { recursive: true });
98-
const copyRecursiveSync = (src, dest) => {
99-
let exists = fs.existsSync(src);
100-
let stats = exists && fs.statSync(src);
101-
let isDirectory = exists && stats.isDirectory();
102-
if (isDirectory) {
103-
if (!fs.existsSync(dest)) {
104-
fs.mkdirSync(dest);
105-
}
106-
107-
fs.readdirSync(src).forEach(function (childItemName) {
108-
copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
109-
});
110-
} else {
111-
fs.copyFileSync(src, dest);
112-
}
113-
};
114-
copyRecursiveSync(path.join(functionDir, answers.runtime.id), functionDir);
115-
116-
fs.rmSync(`${functionDir}/${answers.runtime.id}`, { recursive: true, force: true });
117-
118-
const readmePath = path.join(process.cwd(), 'functions', functionId, 'README.md');
119-
const readmeFile = fs.readFileSync(readmePath).toString();
120-
const newReadmeFile = readmeFile.split('\n');
121-
newReadmeFile[0] = `# ${answers.name}`;
122-
newReadmeFile.splice(1, 2);
123-
fs.writeFileSync(readmePath, newReadmeFile.join('\n'));
124-
125-
let data = {
126-
$id: response['$id'],
127-
name: response.name,
128-
runtime: response.runtime,
129-
execute: response.execute,
130-
events: response.events,
131-
schedule: response.schedule,
132-
timeout: response.timeout,
133-
enabled: response.enabled,
134-
logging: response.logging,
135-
entrypoint: response.entrypoint,
136-
commands: response.commands,
137-
ignore: answers.runtime.ignore || null,
138-
path: `functions/${functionId}`,
139-
};
140-
141-
localConfig.addFunction(data);
142-
success();
143-
}
144-
14531
const pullCollection = async ({ all, databaseId } = {}) => {
14632
const databaseIds = [];
14733

@@ -221,11 +107,6 @@ pull
221107
.description("Pulling your {{ spec.title|caseUcfirst }} project")
222108
.action(actionRunner(pullProject));
223109

224-
pull
225-
.command("function")
226-
.description("Pulling your {{ spec.title|caseUcfirst }} cloud function")
227-
.action(actionRunner(pullFunction))
228-
229110
pull
230111
.command("collection")
231112
.description("Pulling your {{ spec.title|caseUcfirst }} collections")

templates/cli/lib/questions.js.twig

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,44 @@ const questionsCreateProject = [
163163
}
164164
];
165165

166+
const questionsCreateFunction = [
167+
{
168+
type: "input",
169+
name: "name",
170+
message: "What would you like to name your function?",
171+
default: "My Awesome Function"
172+
},
173+
{
174+
type: "input",
175+
name: "id",
176+
message: "What ID would you like to have for your function?",
177+
default: "unique()"
178+
},
179+
{
180+
type: "list",
181+
name: "runtime",
182+
message: "What runtime would you like to use?",
183+
choices: async () => {
184+
let response = await functionsListRuntimes({
185+
parseOutput: false
186+
})
187+
let runtimes = response["runtimes"]
188+
let choices = runtimes.map((runtime, idx) => {
189+
return {
190+
name: `${runtime.name} (${runtime['$id']})`,
191+
value: {
192+
id: runtime['$id'],
193+
entrypoint: getEntrypoint(runtime['$id']),
194+
ignore: getIgnores(runtime['$id']),
195+
commands: getInstallCommand(runtime['$id'])
196+
},
197+
}
198+
})
199+
return choices;
200+
}
201+
}
202+
];
203+
166204
const questionsCreateBucket = [
167205
{
168206
type: "input",
@@ -273,44 +311,6 @@ const questionsPullProject = [
273311
}
274312
];
275313

276-
const questionsPullFunction = [
277-
{
278-
type: "input",
279-
name: "name",
280-
message: "What would you like to name your function?",
281-
default: "My Awesome Function"
282-
},
283-
{
284-
type: "input",
285-
name: "id",
286-
message: "What ID would you like to have for your function?",
287-
default: "unique()"
288-
},
289-
{
290-
type: "list",
291-
name: "runtime",
292-
message: "What runtime would you like to use?",
293-
choices: async () => {
294-
let response = await functionsListRuntimes({
295-
parseOutput: false
296-
})
297-
let runtimes = response["runtimes"]
298-
let choices = runtimes.map((runtime, idx) => {
299-
return {
300-
name: `${runtime.name} (${runtime['$id']})`,
301-
value: {
302-
id: runtime['$id'],
303-
entrypoint: getEntrypoint(runtime['$id']),
304-
ignore: getIgnores(runtime['$id']),
305-
commands: getInstallCommand(runtime['$id'])
306-
},
307-
}
308-
})
309-
return choices;
310-
}
311-
}
312-
];
313-
314314
const questionsPullCollection = [
315315
{
316316
type: "checkbox",
@@ -534,12 +534,12 @@ const questionsMfaChallenge = [
534534

535535
module.exports = {
536536
questionsCreateProject,
537+
questionsCreateFunction,
537538
questionsCreateBucket,
538539
questionsCreateCollection,
539540
questionsCreateMessagingTopic,
540541
questionsPullProject,
541542
questionsLogin,
542-
questionsPullFunction,
543543
questionsPullCollection,
544544
questionsPushFunctions,
545545
questionsPushCollections,

0 commit comments

Comments
 (0)