Skip to content

Commit 501b92d

Browse files
authored
Merge pull request #914 from appwrite/feat-local-variables
CLI: local variables, speed-up build
2 parents d4f2428 + 24192e6 commit 501b92d

File tree

3 files changed

+80
-18
lines changed

3 files changed

+80
-18
lines changed

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

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const Tail = require('tail').Tail;
2+
const { parse: parseDotenv } = require('dotenv');
23
const chalk = require('chalk');
34
const ignore = require("ignore");
45
const tar = require("tar");
@@ -80,6 +81,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
8081
entrypoint: func.entrypoint,
8182
path: func.path,
8283
commands: func.commands,
84+
scopes: func.scopes ?? []
8385
};
8486

8587
drawTable([settings]);
@@ -110,7 +112,9 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
110112
fs.writeFileSync(errorsPath, '');
111113
}
112114

115+
const userVariables = {};
113116
const variables = {};
117+
114118
if(!noVariables) {
115119
try {
116120
const { variables: remoteVariables } = await paginate(functionsListVariables, {
@@ -120,12 +124,24 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
120124

121125
remoteVariables.forEach((v) => {
122126
variables[v.key] = v.value;
127+
userVariables[v.key] = v.value;
123128
});
124129
} catch(err) {
125130
warn("Remote variables not fetched. Production environment variables will not be avaiable. Reason: " + err.message);
126131
}
127132
}
128133

134+
const functionPath = path.join(process.cwd(), func.path);
135+
const envPath = path.join(functionPath, '.env');
136+
if(fs.existsSync(envPath)) {
137+
const env = parseDotenv(fs.readFileSync(envPath).toString() ?? '');
138+
139+
Object.keys(env).forEach((key) => {
140+
variables[key] = env[key];
141+
userVariables[key] = env[key];
142+
});
143+
}
144+
129145
variables['APPWRITE_FUNCTION_API_ENDPOINT'] = globalConfig.getFrom('endpoint');
130146
variables['APPWRITE_FUNCTION_ID'] = func.$id;
131147
variables['APPWRITE_FUNCTION_NAME'] = func.name;
@@ -148,6 +164,13 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
148164
headers['x-appwrite-user-jwt'] = JwtManager.userJwt ?? '';
149165
variables['OPEN_RUNTIMES_HEADERS'] = JSON.stringify(headers);
150166

167+
if(Object.keys(userVariables).length > 0) {
168+
drawTable(Object.keys(userVariables).map((key) => ({
169+
key,
170+
value: userVariables[key].split("").filter((_, i) => i < 16).map(() => "*").join("")
171+
})));
172+
}
173+
151174
await dockerPull(func);
152175

153176
new Tail(logsPath).on("line", function(data) {
@@ -158,10 +181,27 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
158181
});
159182

160183
if(!noReload) {
184+
const ignorer = ignore();
185+
ignorer.add('.appwrite');
186+
ignorer.add('code.tar.gz');
187+
188+
if (func.ignore) {
189+
ignorer.add(func.ignore);
190+
} else if (fs.existsSync(path.join(functionPath, '.gitignore'))) {
191+
ignorer.add(fs.readFileSync(path.join(functionPath, '.gitignore')).toString());
192+
}
193+
161194
chokidar.watch('.', {
162195
cwd: path.join(process.cwd(), func.path),
163196
ignoreInitial: true,
164-
ignored: [ ...(func.ignore ?? []), 'code.tar.gz', '.appwrite', '.appwrite/', '.appwrite/*', '.appwrite/**', '.appwrite/*.*', '.appwrite/**/*.*' ]
197+
ignored: (xpath) => {
198+
const relativePath = path.relative(functionPath, xpath);
199+
200+
if(!relativePath) {
201+
return false;
202+
}
203+
return ignorer.ignores(relativePath);
204+
}
165205
}).on('all', async (_event, filePath) => {
166206
Queue.push(filePath);
167207
});
@@ -187,7 +227,6 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
187227
} else {
188228
log('Hot-swapping function.. Files with change are ' + files.join(', '));
189229

190-
const functionPath = path.join(process.cwd(), func.path);
191230
const hotSwapPath = path.join(functionPath, '.appwrite/hot-swap');
192231
const buildPath = path.join(functionPath, '.appwrite/build.tar.gz');
193232

@@ -201,6 +240,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
201240

202241
await tar
203242
.extract({
243+
keep: true,
204244
gzip: true,
205245
sync: true,
206246
cwd: hotSwapPath,
@@ -211,6 +251,8 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
211251
ignorer.add('.appwrite');
212252
if (func.ignore) {
213253
ignorer.add(func.ignore);
254+
} else if (fs.existsSync(path.join(functionPath, '.gitignore'))) {
255+
ignorer.add(fs.readFileSync(path.join(functionPath, '.gitignore')).toString());
214256
}
215257

216258
const filesToCopy = getAllFiles(functionPath).map((file) => path.relative(functionPath, file)).filter((file) => !ignorer.ignores(file));
@@ -237,8 +279,6 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
237279
file: buildPath
238280
}, ['.']);
239281

240-
fs.rmSync(hotSwapPath, { recursive: true, force: true });
241-
242282
await dockerStart(func, variables, port);
243283
}
244284
} catch(err) {

templates/cli/lib/emulation/docker.js.twig

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
const tar = require("tar");
2+
const ignore = require("ignore");
13
const net = require('net');
24
const chalk = require('chalk');
35
const childProcess = require('child_process');
@@ -6,6 +8,7 @@ const path = require('path');
68
const fs = require('fs');
79
const { log, error, success, hint } = require("../parser");
810
const { openRuntimesVersion, systemTools, Queue } = require("./utils");
11+
const { getAllFiles } = require("../utils");
912

1013
async function dockerStop(id) {
1114
const stopProcess = childProcess.spawn('docker', ['rm', '--force', id], {
@@ -50,7 +53,7 @@ async function dockerBuild(func, variables) {
5053

5154
const params = [ 'run' ];
5255
params.push('--name', id);
53-
params.push('-v', `${functionDir}/:/mnt/code:rw`);
56+
params.push('-v', `${tmpBuildPath}/:/mnt/code:rw`);
5457
params.push('-e', 'APPWRITE_ENV=development');
5558
params.push('-e', 'OPEN_RUNTIMES_ENV=development');
5659
params.push('-e', 'OPEN_RUNTIMES_SECRET=');
@@ -120,9 +123,39 @@ async function dockerBuild(func, variables) {
120123
if (fs.existsSync(tempPath)) {
121124
fs.rmSync(tempPath, { force: true });
122125
}
126+
127+
fs.rmSync(tmpBuildPath, { recursive: true, force: true });
123128
}
124129

125130
async function dockerStart(func, variables, port) {
131+
// Pack function files
132+
const functionDir = path.join(process.cwd(), func.path);
133+
134+
const ignorer = ignore();
135+
ignorer.add('.appwrite');
136+
if (func.ignore) {
137+
ignorer.add(func.ignore);
138+
} else if (fs.existsSync(path.join(functionDir, '.gitignore'))) {
139+
ignorer.add(fs.readFileSync(path.join(functionDir, '.gitignore')).toString());
140+
}
141+
142+
const files = getAllFiles(functionDir).map((file) => path.relative(functionDir, file)).filter((file) => !ignorer.ignores(file));
143+
const tmpBuildPath = path.join(functionDir, '.appwrite/tmp-build');
144+
if (!fs.existsSync(tmpBuildPath)) {
145+
fs.mkdirSync(tmpBuildPath, { recursive: true });
146+
}
147+
148+
for(const f of files) {
149+
const filePath = path.join(tmpBuildPath, f);
150+
const fileDir = path.dirname(filePath);
151+
if (!fs.existsSync(fileDir)) {
152+
fs.mkdirSync(fileDir, { recursive: true });
153+
}
154+
155+
const sourcePath = path.join(functionDir, f);
156+
fs.copyFileSync(sourcePath, filePath);
157+
}
158+
126159
const runtimeChunks = func.runtime.split("-");
127160
const runtimeVersion = runtimeChunks.pop();
128161
const runtimeName = runtimeChunks.join("-");

templates/cli/lib/parser.js.twig

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,9 @@ const drawTable = (data) => {
9090
if (row[key] === null) {
9191
rowValues.push("-");
9292
} else if (Array.isArray(row[key])) {
93-
switch (row[key].length) {
94-
case 1:
95-
if (typeof row[key][0] === 'object') {
96-
rowValues.push(`array(${row[key].length})`);
97-
} else {
98-
rowValues.push(row[key][0]);
99-
}
100-
break;
101-
default:
102-
rowValues.push(`array(${row[key].length})`);
103-
break;
104-
}
93+
rowValues.push(JSON.stringify(row[key]));
10594
} else if (typeof row[key] === 'object') {
106-
rowValues.push("object");
95+
rowValues.push(JSON.stringify(row[key]));
10796
} else {
10897
rowValues.push(row[key]);
10998
}

0 commit comments

Comments
 (0)