-
Notifications
You must be signed in to change notification settings - Fork 6
/
electric.js
288 lines (231 loc) · 9.57 KB
/
electric.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
"use strict";
import * as path from "https://deno.land/std@0.55.0/path/mod.ts";
import { copySync, existsSync } from "https://deno.land/std@0.55.0/fs/mod.ts";
import * as colors from "https://deno.land/std@0.55.0/fmt/colors.ts";
//import { decompress } from "https://deno.land/x/lz4@v0.1.1/mod.ts";
import { readZip } from "https://raw.githubusercontent.com/hayd/deno-zip/6ab1cf5081dbe63d55016a74c79df98025e2b5e3/mod.ts";
import env from "./src/env.js";
import { crossPlatformPathConversion, printProgressBar } from "./src/util.js";
import { cacheDenoModulesLocally, updateRunCommand } from "./src/package.js";
/**
* Returns the cache directory for DenoCEF.
*/
function getCacheDirectory() {
return env("denocef", {suffix: ""}).cache;
}
/**
* Creates a new cache directory for DenoCEF is none exists.
*/
function createCacheDirectory() {
const cacheDirectory = getCacheDirectory();
if (!existsSync(cacheDirectory)) {
Deno.mkdirSync(cacheDirectory, {recursive: true});
}
}
/**
* Fetches, decompresses, and unzips a DenoCEF binary from the repository. Due to
* the size of the binaries, this process will take a long time, and so displays
* some progress over the process.
*
* @param {string} platformName the name of the platform (either "windows",
* "linux", or "darwin")
*
* @todo Implement a more dynamic progress bar. Currently implementations using
* reader is not supported as of Deno v1.0.2 for fetch API, preventing a fetch
* status bar. Additionally, the compression and zip libs don't support these
* features as well, at least not easily.
*/
async function fetchCef(platformName) {
let cefBinaryUrl = `https://github.com/denjucks/deno-cef/releases/download/0.0.1/${platformName}-denocef.zip`;
// Progress message for the initial fetch
console.log();
console.log(colors.cyan(` Step 1/4)`));
console.log(" " + `
Fetching the DenoCEF binaries for ${platformName}. Please wait, as this
process will take a while due to the large size of the binaries.`.trim());
printProgressBar(0,4);
console.log();
// Performing the fetch
await fetch(cefBinaryUrl)
.then(response => response.blob())
.then(async (data) => {
// Making a platform specific directory in the cache if one does
// not already exist
let cacheDirectory = path.join(getCacheDirectory(), platformName);
try { Deno.mkdirSync(cacheDirectory) } catch(e) {}
// Progress message for writing the binaries to disk
console.log(colors.cyan(` Step 2/4)`));
console.log(" " + `
Writing the binaries to
${cacheDirectory}`.trim());
printProgressBar(1,4);
console.log();
// Writing the binaries to the cache
Deno.writeFileSync(path.join(cacheDirectory, platformName+"-denocef.zip"), await data.arrayBuffer());
data = undefined;
});
}
/*
async function decompressCef(platformName) {
let cacheDirectory = path.join(getCacheDirectory(), platformName);
// Progress message for decompressing the fetched binaries.
console.log(colors.cyan(" Step 3/5)"));
console.log(" Decompressing the binaries. Please wait as this process will take a while.");
printProgressBar(2,5);
console.log();
// Decompressing the binaries and removing the old compressed binary file
Deno.writeFileSync(path.join(cacheDirectory, "denocef.zip"), decompress(Deno.readFileSync(path.join(cacheDirectory, platformName+"-denocef.zip.xz"))))
Deno.removeSync(path.join(cacheDirectory, platformName+"-denocef.zip.xz"));
}
*/
async function unzipCef(platformName) {
let cacheDirectory = path.join(getCacheDirectory(), platformName);
// Progress message for unzipping the binaries.
console.log(colors.cyan(" Step 3/4)"));
console.log(" Unarchiving the binaries. Please wait as this process will take a while.");
printProgressBar(2,4);
console.log();
// Unzipping the decompressed binaries
let zip = await readZip(path.join(cacheDirectory, platformName+"-denocef.zip"));
await zip.unzip(cacheDirectory);
zip = undefined;
// Removing the zipped archive
Deno.removeSync(path.join(cacheDirectory, platformName+"-denocef.zip"));
}
/**
* Helper function to create a platform cache directory and run the fetching,
* decompressing, and unzipping function
*
* @param {string} platformNplatformNameame the name of the platform (either "windows",
* "linux", or "darwin")
*/
async function downloadCefToCache(platformName) {
platformName = platformName || Deno.build.os;
switch (platformName) {
case "windows":
Deno.mkdirSync(path.join(getCacheDirectory(), "windows"));
break;
case "darwin":
Deno.mkdirSync(path.join(getCacheDirectory(), "darwin"));
break;
case "linux":
Deno.mkdirSync(path.join(getCacheDirectory(), "linux"));
break;
}
await fetchCef(platformName);
}
/**
* Clears the cache for a platform.
*
* @param {string} platformName the name of the platform (either "windows",
* "linux", or "darwin")
*/
function clearCefCache(platformName) {
Deno.removeSync(path.join(getCacheDirectory(), platformName || Deno.build.os), { recursive: true });
}
/**
* Creates a new DenoCEF project in the current directory
*
* @param {string} platformName the name of the platform (either "windows",
* "linux", or "darwin")
*/
function createNewProject(platformName) {
const cacheDirectoryPath = getCacheDirectory();
const platformCacheDirectoryPath = path.join(cacheDirectoryPath, platformName || Deno.build.os);
const __dirname = crossPlatformPathConversion(Deno.cwd());
if (existsSync(path.join(__dirname, "DenoCefProject"))) {
console.log(colors.yellow("Project already exists in this directory. No new project created."));
} else {
console.log(colors.cyan(" Step 4/4)"));
console.log(` Copying ${platformName} cache into new project folder`);
printProgressBar(3,4);
console.log();
copySync(platformCacheDirectoryPath, path.join(__dirname, "DenoCefProject"));
console.log(` Finished creating the new DenoCEF project`);
printProgressBar(4,4);
console.log();
}
}
/**
* The Electric CLI
*/
if (import.meta.main) {
let platformName = Deno.args[1] || Deno.build.os;
if (Deno.build.os === "darwin") {
console.log(colors.red("DenoCEF currently does not support MacOS, but is planned in the future. For the time being, please develop your application on either Windows or Linux until full support is added."));
} else {
switch (Deno.args[0]) {
/*
case "fetch":
if (platformName === "mac") {platformName = "darwin";}
if (!existsSync(getCacheDirectory())) {
createCacheDirectory();
}
if (!existsSync(path.join(getCacheDirectory(), platformName))) {
await downloadCefToCache(platformName);
}
break;
*/
/*
case "decompress":
await decompressCef(platformName);
break;
*/
/*
case "unzip":
await unzipCef(platformName);
break;
*/
case "create":
if (platformName === "mac") {platformName = "darwin";}
if (!existsSync(getCacheDirectory())) {
createCacheDirectory();
}
if (!existsSync(path.join(getCacheDirectory(), platformName))) {
await downloadCefToCache(platformName);
await unzipCef(platformName);
}
createNewProject(platformName);
break;
case "refresh":
if (platformName === "mac") {platformName = "darwin";}
clearCefCache(platformName);
break;
case "package":
cacheDenoModulesLocally();
updateRunCommand();
break;
default:
console.log(`
${colors.cyan("Electric")} - A CLI for DenoCEF
Copyright 2020 - Anthony Mancini
Licensed under an MIT license
Requirements:
-------------
Before running Electric commands, it is recommended you have approximately
4 GB of available RAM and 5 GB of disk space (at minimum you should have
2.5 GB of available RAM and 3 GB of disk space). These requirements are
only for downloading the binaries, and less RAM is needed to actually run
the DenoCEF programs.
Available Commands:
-------------------
${colors.cyan("create [<platform>]")}
| Creates a new DenoCEF project in the current directory. If no
| DenoCEF binaries are found for the target platform, first fetches
| those binaries from the repository and caches them. Once cached,
| this command will use the cached binaries to significantly speed
| up the process of creating new DenoCEF apps.
|
| Note that if no platform is chosen, your platform is used (for
| example if you are running this on Windows, the Windows binaries
| will be fetched).
${colors.cyan("refresh [<platform>]")}
| Clears the cache of the binaries for a particular platform, or your
| platform if none is chosen.
${colors.cyan("package")}
| Packages your DenoCEF application into a single zip file that can
| be shipped to other users.
`);
}
}
}