Skip to content

Commit d38b69f

Browse files
committed
implement local development, environment variables, speed-up build
1 parent 2e503d6 commit d38b69f

File tree

4 files changed

+84
-18
lines changed

4 files changed

+84
-18
lines changed

templates/cli/base/params.twig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
const func = localConfig.getFunction(functionId);
1818

1919
ignorer.add('.appwrite');
20+
ignorer.add('.DS_Store');
2021

2122
if (func.ignore) {
2223
ignorer.add(func.ignore);

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

Lines changed: 46 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,28 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
158181
});
159182

160183
if(!noReload) {
184+
const ignorer = ignore();
185+
ignorer.add('.appwrite');
186+
ignorer.add('.DS_Store');
187+
ignorer.add('code.tar.gz');
188+
189+
if (func.ignore) {
190+
ignorer.add(func.ignore);
191+
} else if (fs.existsSync(path.join(functionPath, '.gitignore'))) {
192+
ignorer.add(fs.readFileSync(path.join(functionPath, '.gitignore')).toString());
193+
}
194+
161195
chokidar.watch('.', {
162196
cwd: path.join(process.cwd(), func.path),
163197
ignoreInitial: true,
164-
ignored: [ ...(func.ignore ?? []), 'code.tar.gz', '.appwrite', '.appwrite/', '.appwrite/*', '.appwrite/**', '.appwrite/*.*', '.appwrite/**/*.*' ]
198+
ignored: (xpath) => {
199+
const relativePath = path.relative(functionPath, xpath);
200+
201+
if(!relativePath) {
202+
return false;
203+
}
204+
return ignorer.ignores(relativePath);
205+
}
165206
}).on('all', async (_event, filePath) => {
166207
Queue.push(filePath);
167208
});
@@ -187,7 +228,6 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
187228
} else {
188229
log('Hot-swapping function.. Files with change are ' + files.join(', '));
189230

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

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

202242
await tar
203243
.extract({
244+
keep: true,
204245
gzip: true,
205246
sync: true,
206247
cwd: hotSwapPath,
@@ -209,8 +250,11 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
209250

210251
const ignorer = ignore();
211252
ignorer.add('.appwrite');
253+
ignorer.add('.DS_Store');
212254
if (func.ignore) {
213255
ignorer.add(func.ignore);
256+
} else if (fs.existsSync(path.join(functionPath, '.gitignore'))) {
257+
ignorer.add(fs.readFileSync(path.join(functionPath, '.gitignore')).toString());
214258
}
215259

216260
const filesToCopy = getAllFiles(functionPath).map((file) => path.relative(functionPath, file)).filter((file) => !ignorer.ignores(file));
@@ -237,8 +281,6 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
237281
file: buildPath
238282
}, ['.']);
239283

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

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

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
const tar = require("tar");
2+
const ignore = require("ignore");
13
const chalk = require('chalk');
24
const childProcess = require('child_process');
35
const { localConfig } = require("../config");
46
const path = require('path');
57
const fs = require('fs');
68
const { log, success, hint } = require("../parser");
79
const { openRuntimesVersion, systemTools, Queue } = require("./utils");
10+
const { getAllFiles } = require("../utils");
811

912
async function dockerStop(id) {
1013
const stopProcess = childProcess.spawn('docker', ['rm', '--force', id], {
@@ -49,7 +52,7 @@ async function dockerBuild(func, variables) {
4952

5053
const params = [ 'run' ];
5154
params.push('--name', id);
52-
params.push('-v', `${functionDir}/:/mnt/code:rw`);
55+
params.push('-v', `${tmpBuildPath}/:/mnt/code:rw`);
5356
params.push('-e', 'APPWRITE_ENV=development');
5457
params.push('-e', 'OPEN_RUNTIMES_ENV=development');
5558
params.push('-e', 'OPEN_RUNTIMES_SECRET=');
@@ -120,9 +123,40 @@ 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+
ignorer.add('.DS_Store');
137+
if (func.ignore) {
138+
ignorer.add(func.ignore);
139+
} else if (fs.existsSync(path.join(functionDir, '.gitignore'))) {
140+
ignorer.add(fs.readFileSync(path.join(functionDir, '.gitignore')).toString());
141+
}
142+
143+
const files = getAllFiles(functionDir).map((file) => path.relative(functionDir, file)).filter((file) => !ignorer.ignores(file));
144+
const tmpBuildPath = path.join(functionDir, '.appwrite/tmp-build');
145+
if (!fs.existsSync(tmpBuildPath)) {
146+
fs.mkdirSync(tmpBuildPath, { recursive: true });
147+
}
148+
149+
for(const f of files) {
150+
const filePath = path.join(tmpBuildPath, f);
151+
const fileDir = path.dirname(filePath);
152+
if (!fs.existsSync(fileDir)) {
153+
fs.mkdirSync(fileDir, { recursive: true });
154+
}
155+
156+
const sourcePath = path.join(functionDir, f);
157+
fs.copyFileSync(sourcePath, filePath);
158+
}
159+
126160
const runtimeChunks = func.runtime.split("-");
127161
const runtimeVersion = runtimeChunks.pop();
128162
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)