basically implement all wechat-devtools build scripts

This commit is contained in:
Minun 2020-02-04 04:34:34 +08:00
commit a8d015c0ab
22 changed files with 714 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
nwjs/
node/
package.nw/
cache/
tmp/

16
bin/wechat-devtools Executable file
View File

@ -0,0 +1,16 @@
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
cd $APPDATA/..
export WECHAT_DEVTOOLS_DIR="$DIR/../nwjs"
export APPDATA="$DIR/../nwjs"
exec "$DIR"/../nwjs/nw "$@" --load-extension="$DIR"/../nwjs/package.nw/js/ideplugin "$@"

4
conf/node.json Normal file
View File

@ -0,0 +1,4 @@
{
"version": "12.6.0",
"url": "https://npm.taobao.org/mirrors/node/v${version}/node-v${version}-linux-x64.tar.gz"
}

4
conf/nwjs.json Normal file
View File

@ -0,0 +1,4 @@
{
"version": "0.39.3",
"url": "https://npm.taobao.org/mirrors/nwjs/v${version}/nwjs-sdk-v${version}-linux-x64.tar.gz"
}

92
patch/nw-menu.js Normal file
View File

@ -0,0 +1,92 @@
if (typeof nw === "undefined") {
return;
}
let log = function (content) {
process.stderr.write(content + "\n");
};
let originMenuItem = nw.MenuItem;
nw.MenuItem = function MenuItem(options) {
options = Object.assign({}, options);
delete options.shortcutName;
delete options.shouldEnabled;
if (options.label) {
if (options.label.indexOf("[") !== -1) {
let rest = options.label.split("[").slice(1).join("[").trim();
if (rest[rest.length - 1] === "]") {
rest = rest.slice(0, -1).split("+").map((x) => {
if (!x) { return "+" }
switch (x) {
case "↓": { return "Down"; }
case "↑": { return "Up"; }
case "PAGE↓": { return "PageDown"; }
case "PAGE↑": { return "PageUp"; }
case "←": { return "Left"; }
case "→": { return "Right"; }
default: { return x; }
}
});
if (rest.length > 1) {
options.key = rest[rest.length - 1];
options.modifiers = rest.slice(0, -1).join("+");
} else {
options.key = rest[0];
}
}
options.label = options.label.split("[")[0];
}
if (options.label.indexOf("(&") !== -1) {
options.label = options.label.split("(&")[0];
}
options.label = options.label.replace("&", "").trim();
switch (options.label) {
case "Go to Declaration": { options.label = "转到声明"; break; }
case "Go to References": { options.label = "转到引用"; break; }
case "Find All References": { options.label = "查找所有引用"; break; }
case "Find All Implementations": { options.label = "查找所有实现"; break; }
}
}
return new originMenuItem(options);
};
let originAppend = nw.Menu.prototype.append;
nw.Menu.prototype.append = function (item) {
if (item.parentMenu) {
item.parentMenu.remove(item);
}
item.parentMenu = this;
if ((this.items.length > 0) &&
(this.items[this.items.length - 1].type === "separator") &&
(item.type === "separator")) {
originInsert.call(this, item, this.items.length);
return;
}
if ((this.items.length === 0) && (item.type === "separator")) {
originInsert.call(this, item, this.items.length);
return;
}
return originAppend.call(this, item);
};
let originInsert = nw.Menu.prototype.insert;
nw.Menu.prototype.insert = function (item, index) {
if (item.parentMenu) {
item.parentMenu.remove(item);
}
item.parentMenu = this;
return originInsert.call(this, item, index);
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 61.2 (89653) - https://sketch.com -->
<title>wechat-devtools</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#0E142C" offset="0%"></stop>
<stop stop-color="#323C67" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50%" y1="0%" x2="50%" y2="98.8835515%" id="linearGradient-2">
<stop stop-color="#EEEEEE" offset="0%"></stop>
<stop stop-color="#D7D7D7" offset="100%"></stop>
</linearGradient>
<text id="text-3" font-family="Menlo-Bold, Menlo" font-size="230" font-weight="bold">
<tspan x="212" y="688">&lt;/&gt;</tspan>
</text>
<filter x="-3.4%" y="-4.4%" width="106.9%" height="112.4%" filterUnits="objectBoundingBox" id="filter-4">
<feOffset dx="0" dy="5" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.761991914 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<filter x="-9.7%" y="-11.8%" width="123.0%" height="128.1%" filterUnits="objectBoundingBox" id="filter-5">
<feOffset dx="0" dy="10" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="10" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.272536058 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
<feMerge>
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-6">
<stop stop-color="#9EEE69" offset="0%"></stop>
<stop stop-color="#74CD30" offset="100%"></stop>
</linearGradient>
<filter x="-8.1%" y="-9.1%" width="116.2%" height="118.2%" filterUnits="objectBoundingBox" id="filter-7">
<feOffset dx="0" dy="5" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"></feColorMatrix>
<feMerge>
<feMergeNode in="shadowMatrixOuter1"></feMergeNode>
<feMergeNode in="SourceGraphic"></feMergeNode>
</feMerge>
</filter>
<linearGradient x1="50%" y1="0.269214527%" x2="50%" y2="100%" id="linearGradient-8">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#E5E9EA" offset="100%"></stop>
</linearGradient>
</defs>
<g id="wechat-devtools" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<rect id="Rectangle" fill="url(#linearGradient-1)" x="95" y="157" width="832" height="710" rx="34"></rect>
<path d="M898,153 C916.777681,153 932,168.222319 932,187 L932,837 C932,855.777681 916.777681,871 898,871 L125,871 C106.222319,871 91,855.777681 91,837 L91,187 C91,168.222319 106.222319,153 125,153 L898,153 Z M877,199 L148,199 C141.924868,199 137,203.924868 137,210 L137,210 L137,816 C137,822.075132 141.924868,827 148,827 L148,827 L877,827 C883.075132,827 888,822.075132 888,816 L888,816 L888,210 C888,203.924868 883.075132,199 877,199 L877,199 Z" id="Combined-Shape" fill="url(#linearGradient-2)"></path>
<g id="&lt;/&gt;" opacity="0.0783110119" fill="#FFFFFF">
<use fill-opacity="1" filter="url(#filter-4)" xlink:href="#text-3"></use>
<use fill-rule="evenodd" xlink:href="#text-3"></use>
<use fill-opacity="1" xlink:href="#text-3"></use>
</g>
<g id="Group-3" filter="url(#filter-5)" transform="translate(211.000000, 266.000000)">
<g id="Group-4">
<path d="M216.5,364 C336.069648,364 433,282.515824 433,182 C433,81.4841755 336.069648,-2.84217094e-14 216.5,-2.84217094e-14 C96.9303517,-2.84217094e-14 0,81.4841755 0,182 C0,234.824118 26.7704343,282.392034 69.5285421,315.639256 C93.3413194,334.155246 58.2521249,377.054783 69.5285421,386.023056 C80.8049593,394.99133 128.568238,347 151.295389,355.600627 C171.060829,363.080455 193.777604,364 216.5,364 Z" id="Oval-Copy" fill="url(#linearGradient-6)"></path>
<circle id="Oval" fill="#126F20" cx="143.5" cy="126.5" r="29.5"></circle>
<circle id="Oval-Copy-2" fill="#126F20" cx="289.5" cy="126.5" r="29.5"></circle>
</g>
<g id="Group-5" filter="url(#filter-7)" transform="translate(237.000000, 167.000000)">
<path d="M182,305 C200.898516,305 228.587306,302.288693 236.262178,298.107116 C255.747671,287.490639 287.208639,328.334705 303.2061,323 C319.203561,317.665295 280.639295,283.352792 303.2061,265.082731 C337.702449,237.154525 364,195.852984 364,152.5 C364,68.2765757 282.515824,2.84217094e-14 182,2.84217094e-14 C81.4841755,2.84217094e-14 0,68.2765757 0,152.5 C0,236.723424 81.4841755,305 182,305 Z" id="Oval" fill="url(#linearGradient-8)"></path>
<circle id="Oval-Copy-3" fill="#7B7F7F" cx="244.5" cy="107.5" r="24.5"></circle>
<circle id="Oval-Copy-4" fill="#7B7F7F" cx="119.5" cy="107.5" r="24.5"></circle>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

12
res/template.desktop Normal file
View File

@ -0,0 +1,12 @@
[Desktop Entry]
Name=WeChat Dev Tools
Name[zh_CN]=
Comment=The development tools for wechat projects
Comment[zh_CN]=IDE
Categories=Development;WebDevelopment;IDE;
Exec=${dir}/bin/wechat-devtools
Icon=wechat-devtools
Type=Application
Terminal=false
StartupWMClass=wechat_devtools
Actions=

14
tools/fix-editor-font Executable file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env mew_js
@info("Writing editor configs");
const fontFamily = "'Mew Source SC', 'Source Code Pro', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace";
let configPath = @.fs.homePath(".config/wechat_devtools/Default/Editor/User/settings.json");
let config = JSON.parse(@.fs.readFile.sync(configPath, "utf8"));
config["editor.fontFamily"] = fontFamily;
@.fs.makeDirs(@.fs.dirname(configPath));
@.fs.writeFile.sync(configPath, JSON.stringify(config, null, 4));

18
tools/fix-package-name Executable file
View File

@ -0,0 +1,18 @@
#!/usr/bin/env mew_js
const parseFile = function (path) {
if (!@.fs.exists(path)) {
return;
}
let content = JSON.parse(@.fs.readFile.sync(path, "utf8"));
content.name = "wechat_devtools";
@.fs.writeFile.sync(path, JSON.stringify(content, null, 4));
};
parseFile(@path(__dirname, "../package.nw/package.json"));
parseFile(@path(__dirname, "../package.nw/package-lock.json"));

22
tools/install-desktop-icon Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env mew_js
for (let size of ["64", "128", "256", "512"]) {
let iconPath = @.fs.homePath(`.local/share/icons/hicolor/${size}x${size}/wechat-devtools.png`);
@.fs.makeDirs(@.fs.dirname(iconPath));
@info(`Writing icon file ${iconPath}`);
@.fs.copyFile.sync(@path(__dirname, "../res/icons", `wechat-devtools${size}.png`), iconPath);
}
let svgPath = @.fs.homePath(".local/share/icons/hicolor/scalable/wechat-devtools.svg");
@.fs.makeDirs(@.fs.dirname(svgPath));
@info(`Writing icon file ${svgPath}`);
@.fs.copyFile.sync(@path(__dirname, "../res/icons/wechat-devtools.svg"), svgPath);
let desktopCode = @.format(@.fs.readFile.sync(@path(__dirname, "../res/template.desktop"), "utf8"), {
"dir": (@path(__dirname, ".."))
});
desktopPath = @.fs.homePath(".local/share/applications/wechat-devtools.desktop");
@.fs.makeDirs(@.fs.dirname(desktopPath));
@info(`Writing desktop file ${desktopPath}`);
@.fs.writeFile.sync(desktopPath, desktopCode);

32
tools/patch-wechat-devtools Executable file
View File

@ -0,0 +1,32 @@
#!/usr/bin/env mew_js
let code = @.fs.readFile.sync(@path(__dirname, "../package.nw/js/unpack/hackrequire/index.js"), "utf8");
let signatureBegin = "/* patch wechat devtools begin */\n";
let signatureEnd = "/* patch wechat devtools end */\n";
let index = code.indexOf(signatureBegin);
let patch = @.fs.listFiles(@path(__dirname, "../patch")).map((file) => {
if ((file.name[0] !== ".") && (@.fs.extname(file.name) === ".js")) {
return (`/* ${file.name} */\n` +
"(() => {\n\n" +
" try {\n\n" +
@.fs.readFile.sync(@path(__dirname, "../patch", file.name), "utf8").trim().split("\n").map((line) => {
return " " + line;
}).join("\n") + "\n\n" +
" } catch (error) {\n" +
" process.stderr.write(error.message);\n" +
" process.stderr.write(error.stack);\n" +
" }\n\n" +
"})();");
}
return "";
}).join("\n").trim() + "\n";
if (code.indexOf(signatureBegin) !== -1) {
code = code.split(signatureEnd).slice(1).join(signatureEnd);
}
@.fs.writeFile.sync(@path(__dirname, "../package.nw/js/unpack/hackrequire/index.js"),
signatureBegin + patch + signatureEnd + code);

36
tools/rebuild-node-modules Executable file
View File

@ -0,0 +1,36 @@
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
package_dir="$DIR/../package.nw"
export PATH=$DIR/../node/bin:$PATH
rm -fr "${package_dir}/node_modules/vscode-windows-ca-certs" # the module is only available in windows
rm -fr "${package_dir}/node_modules/vscode-ripgrep/bin" # redownload bin on linux
rm -fr "${package_dir}/node_modules/nodegit/build" # rebuild nodegit
(cd "${package_dir}/node_modules" && find -name *.pdb | xargs -I{} rm -r {}) # remove pdb debugging file
rm -fr "${package_dir}/node_modules_tmp" # remove previous hacking tmp
mkdir -p "${package_dir}/node_modules_tmp"
cp -fr "${package_dir}/node_modules" "${package_dir}/node_modules_tmp/node_modules"
(cd "${package_dir}/node_modules_tmp" && npm install --registry=https://registry.npm.taobao.org) # prepare package.json and dependencies
(cd "${package_dir}/node_modules_tmp" && npm rebuild --registry=https://registry.npm.taobao.org) # rebuild gyp
mkdir -p "${package_dir}/node_modules/nodegit/build/Release"
(cd "${package_dir}/node_modules_tmp/node_modules" && find -name *.node | xargs -I{} cp -r {} ${package_dir}/node_modules/{})
# mkdir -p "${package_dir}/node_modules/vscode-ripgrep/bin"
cp -fr "${package_dir}/node_modules_tmp/node_modules/vscode-ripgrep/bin" "${package_dir}/node_modules/vscode-ripgrep/bin"
rm -fr "${package_dir}/node_modules_tmp"

42
tools/setup-wechat-devtools Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env mew_js
@.async(function () {
@info("Initializing node");
if (@.fs.exists(@path(__dirname, "../node"))) {
this.next(); return;
}
@.task.execute(@path(__dirname, "update-node"), [], false, this.test);
}).then(function () {
@info("Initializing nwjs");
if (@.fs.exists(@path(__dirname, "../nwjs"))) {
this.next(); return;
}
@.task.execute(@path(__dirname, "update-nwjs"), [], false, this.test);
}).then(function () {
@info("Initializing wechat-devtools package");
if (@.fs.exists(@path(__dirname, "../package.nw"))) {
this.next(); return;
}
@.task.execute(@path(__dirname, "update-wechat-devtools"), [], false, this.test);
}).finished((error) => {
if (error) {
@error(error);
process.exit(1);
}
@celebr(`Succeeded setting up wechat-devtools`);
});

100
tools/update-node Executable file
View File

@ -0,0 +1,100 @@
#!/usr/bin/env mew_js
const node = require("../conf/node.json");
@.async(function () {
@.fs.makeDirs(@path(__dirname, "../cache"));
let client = @.net.httpClient();
let url = @.format(node.url, { "version": node.version });
let localPath = @path(__dirname, "../cache", url.split("?")[0].split("/").slice(-1)[0]);
if (@.fs.exists(localPath)) {
@info(`Cache available ${@.fs.filename(localPath)}`);
this.next(localPath);
return;
}
let lastSize = 0;
let lastProgress = 0;
let lastTime = Date.now();
@info(`Downloading ${url}`);
client.download(url, localPath, {
"resumeBroken": true,
"redirects": Object.create(null),
"onSuccess": () => {
this.next(localPath);
},
"onProgress": (size, total) => {
let progress = size / total * 100;
let now = Date.now();
if ((progress - lastProgress > 10) ||
(now - lastTime > 1000)) {
let speed = (size - lastSize) / (now - lastTime) * 1000 / 1024;
lastSize = size;
lastTime = now;
lastProgress = progress;
@info(`Downloaded ${@.fs.filename(localPath)}: ${progress.toFixed(2)}%, speed ${speed.toFixed(2)} KiB/s`);
}
},
"onError": this.reject
});
}).then(function (localPath) {
@info(`Extracting ${localPath}`);
let extractPath = @path(__dirname, `../tmp/${@.fs.basename(localPath)}`);
@.fs.deleteFile.sync(extractPath);
@.fs.makeDirs(extractPath);
@.task.execute("tar", ["xf", localPath], extractPath, (error) => {
if (error) {
this.reject(error); return;
}
this.next(extractPath);
});
}).then(function (extractPath) {
@info(`Upgrading ${@.fs.filename(extractPath)}`);
@.fs.deleteFile.sync(@path(__dirname, "../node"));
@.fs.moveFile.sync(@path(extractPath, @.fs.listFiles(extractPath)[0].name),
@path(__dirname, "../node"))
@.fs.deleteFile.sync(extractPath);
if (@.fs.exists(@path(__dirname, "../nwjs"))) {
if (!@.fs.exists(@path(__dirname, "../nwjs/node"))) {
@.fs.linkFile("../node/bin/node", @path(__dirname, "../nwjs/node"));
}
if (!@.fs.exists(@path(__dirname, "../nwjs/node.exe"))) {
@.fs.linkFile("node", @path(__dirname, "../nwjs/node.exe"));
}
}
this.next();
}).finished((error) => {
if (error) {
@error(error);
process.exit(1);
}
@celebr(`Succeeded upgrading node to version ${node.version}`);
process.exit(0);
});

99
tools/update-nwjs Executable file
View File

@ -0,0 +1,99 @@
#!/usr/bin/env mew_js
const nwjs = require("../conf/nwjs.json");
@.async(function () {
@.fs.makeDirs(@path(__dirname, "../cache"));
let client = @.net.httpClient();
let url = @.format(nwjs.url, { "version": nwjs.version });
let localPath = @path(__dirname, "../cache", url.split("?")[0].split("/").slice(-1)[0]);
if (@.fs.exists(localPath)) {
@info(`Cache available ${@.fs.filename(localPath)}`);
this.next(localPath);
return;
}
let lastSize = 0;
let lastProgress = 0;
let lastTime = Date.now();
@info(`Downloading ${url}`);
client.download(url, localPath, {
"resumeBroken": true,
"redirects": Object.create(null),
"onSuccess": () => {
this.next(localPath);
},
"onProgress": (size, total) => {
let progress = size / total * 100;
let now = Date.now();
if ((progress - lastProgress > 10) ||
(now - lastTime > 1000)) {
let speed = (size - lastSize) / (now - lastTime) * 1000 / 1024;
lastSize = size;
lastTime = now;
lastProgress = progress;
@info(`Downloaded ${@.fs.filename(localPath)}: ${progress.toFixed(2)}%, speed ${speed.toFixed(2)} KiB/s`);
}
},
"onError": this.reject
});
}).then(function (localPath) {
@info(`Extracting ${localPath}`);
let extractPath = @path(__dirname, `../tmp/${@.fs.basename(localPath)}`);
@.fs.deleteFile.sync(extractPath);
@.fs.makeDirs(extractPath);
@.task.execute("tar", ["xf", localPath], extractPath, (error) => {
if (error) {
this.reject(error); return;
}
this.next(extractPath);
});
}).then(function (extractPath) {
@info(`Upgrading ${@.fs.filename(extractPath)}`);
@.fs.deleteFile.sync(@path(__dirname, "../nwjs"));
@.fs.moveFile.sync(@path(extractPath, @.fs.listFiles(extractPath)[0].name),
@path(__dirname, "../nwjs"))
@.fs.deleteFile.sync(extractPath);
if (@.fs.exists(@path(__dirname, "../node/bin/node"))) {
@.fs.linkFile("../node/bin/node", @path(__dirname, "../nwjs/node"));
@.fs.linkFile("node", @path(__dirname, "../nwjs/node.exe"));
}
if (!@.fs.exists(@path(__dirname, "../package.nw"))) {
@.fs.linkFile("../package.nw", @path(__dirname, "../nwjs/package.nw"));
}
this.next();
}).finished((error) => {
if (error) {
@error(error);
process.exit(1);
}
@celebr(`Succeeded upgrading nwjs to version ${nwjs.version}`);
process.exit(0);
});

135
tools/update-wechat-devtools Executable file
View File

@ -0,0 +1,135 @@
#!/usr/bin/env mew_js
const http = require("http");
const url = "https://servicewechat.com/wxa-dev-logic/download_redirect?type=x64&from=mpwiki";
let version = undefined;
const packageDir = "$APPDATA/Tencent/微信开发者工具/package.nw";
@.async(function () {
@.fs.makeDirs(@path(__dirname, "../cache"));
@info(`Downloading ${url}`);
let localPath = @path(__dirname, "../cache/wechat-devtools-x64.exe");
let client = @.net.httpClient();
let lastSize = 0;
let lastProgress = 0;
let lastTime = Date.now();
let filename = "wechat-devtools-x64.exe";
@.fs.deleteFile.sync(localPath);
client.download(url, localPath, {
"redirects": Object.create(null),
"onSuccess": () => {
let newPath = @path(__dirname, "../cache", filename);
@.fs.moveFile(localPath, newPath);
this.next(newPath);
},
"onRedirect": (location) => {
@info(`Redirected to ${location}`);
filename = location.split("?")[0].split("/").slice(-1)[0];
version = filename.split("_").filter((x) => /^[0-9]+\.[0-9]+.[0-9]+$/.test(x))[0];
let newPath = @path(__dirname, "../cache", filename);
if (@.fs.exists(newPath)) {
this.next(newPath);
return true;
}
},
"onProgress": (size, total) => {
let progress = size / total * 100;
let now = Date.now();
if ((progress - lastProgress > 10) ||
(now - lastTime > 1000)) {
let speed = (size - lastSize) / (now - lastTime) * 1000 / 1024;
lastSize = size;
lastTime = now;
lastProgress = progress;
@info(`Downloaded ${filename}: ${progress.toFixed(2)}%, speed ${speed.toFixed(2)} KiB/s`);
}
},
"onError": this.reject
});
}).then(function (localPath) {
@info(`Extracting ${localPath}`);
let extractPath = @path(__dirname, `../tmp/${@.fs.basename(localPath)}`);
@.fs.deleteFile.sync(extractPath);
@.fs.makeDirs(extractPath);
@.task.execute("7z", ["x", localPath, `-o${extractPath}`, packageDir], extractPath, (error) => {
if (error) {
this.reject(error); return;
}
this.next(extractPath);
});
}).then(function (extractPath) {
@info(`Upgrading ${@.fs.filename(extractPath)}`);
@.fs.deleteFile.sync(@path(__dirname, "../package.nw"));
@.fs.moveFile.sync(@path(extractPath, packageDir),
@path(__dirname, "../package.nw"));
@.fs.deleteFile.sync(extractPath);
if (@.fs.exists(@path(__dirname, "../nwjs"))) {
if (!@.fs.exists(@path(__dirname, "../nwjs/package.nw"))) {
@.fs.linkFile("../package.nw", @path(__dirname, "../nwjs/package.nw"));
}
}
this.next();
}).then(function () {
@info("Fixing wechat-devtools package name");
@.task.execute(@path(__dirname, "fix-package-name"), [], false, this.test);
}).then(function () {
@info("Fix wechat-devtools editor font");
@.task.execute(@path(__dirname, "fix-editor-font"), [], false, this.test);
}).then(function () {
@info("Rebuilding wechat-devtools node modules");
@.task.execute(@path(__dirname, "rebuild-node-modules"), [], false, this.test);
}).then(function () {
@info("Patching wechat-devtools");
@.task.execute(@path(__dirname, "patch-wechat-devtools"), [], false, this.test);
}).finished((error) => {
if (error) {
@error(error);
process.exit(1);
}
@celebr(`Succeeded upgrading wechat-devtools to version ${version}`);
process.exit(0);
});

12
tools/wechat-devtools-env.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/sh
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
export PATH=$DIR/../node/bin:$PATH
export PATH=$DIR/../nwjs:$PATH