mirror of
https://github.com/CringeStudios/element-desktop.git
synced 2025-01-18 23:44:59 +01:00
Merge pull request #1 from vector-im/dbkr/make_it_work
Build electron app from pre-built tarball
This commit is contained in:
commit
4cad44a54f
8
.buildkite/pipeline.yaml
Normal file
8
.buildkite/pipeline.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
steps:
|
||||
- label: ":eslint: Lint"
|
||||
command:
|
||||
- "yarn install"
|
||||
- "yarn lint"
|
||||
plugins:
|
||||
- docker#v3.0.1:
|
||||
image: "node:10"
|
19
.eslintrc.js
Normal file
19
.eslintrc.js
Normal file
@ -0,0 +1,19 @@
|
||||
const jsSdkEslintCfg = require('matrix-js-sdk/.eslintrc');
|
||||
|
||||
module.exports = {
|
||||
parserOptions: {
|
||||
ecmaVersion: 8,
|
||||
},
|
||||
env: {
|
||||
node: true,
|
||||
// we also have some browser code (ie. the preload script)
|
||||
browser: true,
|
||||
},
|
||||
extends: ["eslint:recommended", "google"],
|
||||
rules: jsSdkEslintCfg.rules,
|
||||
}
|
||||
|
||||
// js-sdk uses a babel rule which we can't use because we
|
||||
// don't use babel, so remove it & put the original back
|
||||
delete module.exports.rules["babel/no-invalid-this"];
|
||||
module.exports.rules["no-invalid-this"] = "error";
|
7
README
Normal file
7
README
Normal file
@ -0,0 +1,7 @@
|
||||
Riot Desktop
|
||||
============
|
||||
|
||||
This is *not* where the source for Riot desktop lives... yet. As of now,
|
||||
it still lives in the main riot-web repo: https://github.com/vector-im/riot-web
|
||||
|
||||
This is an experimental split-out of the Riot desktop code from the main repo.
|
87
package.json
Normal file
87
package.json
Normal file
@ -0,0 +1,87 @@
|
||||
{
|
||||
"name": "riot-desktop",
|
||||
"productName": "Riot",
|
||||
"main": "src/electron-main.js",
|
||||
"version": "1.5.5",
|
||||
"description": "A feature-rich client for Matrix.org",
|
||||
"author": "New Vector Ltd.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vector-im/riot-desktop"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"files": [],
|
||||
"scripts": {
|
||||
"mkdirs": "mkdir -p packages && mkdir -p deploys",
|
||||
"fetch": "yarn run mkdirs && scripts/fetch-package.js",
|
||||
"check": "scripts/check-webapp.js",
|
||||
"start": "yarn run check && yarn install:electron && electron .",
|
||||
"install:electron": "electron-builder install-app-deps",
|
||||
"lint": "eslint src/",
|
||||
"build:electron": "yarn check && electron-builder",
|
||||
"clean": "rimraf webapp dist packages deploys"
|
||||
},
|
||||
"dependencies": {
|
||||
"auto-launch": "^5.0.1",
|
||||
"electron-store": "^2.0.0",
|
||||
"electron-window-state": "^4.1.0",
|
||||
"minimist": "^1.2.0",
|
||||
"png-to-ico": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron-builder": "^21.2.0",
|
||||
"electron-builder-squirrel-windows": "^21.2.0",
|
||||
"electron-devtools-installer": "^2.2.4",
|
||||
"electron-notarize": "^0.2.0",
|
||||
"eslint": "^5.8.0",
|
||||
"eslint-config-google": "^0.7.1",
|
||||
"eslint-plugin-babel": "^4.1.2",
|
||||
"follow-redirects": "^1.9.0",
|
||||
"matrix-js-sdk": "^2.4.6-rc.1",
|
||||
"tar": "^5.0.5"
|
||||
},
|
||||
"build": {
|
||||
"appId": "im.riot.app",
|
||||
"electronVersion": "7.1.3",
|
||||
"files": [
|
||||
"node_modules/**",
|
||||
"src/**"
|
||||
],
|
||||
"extraResources": [
|
||||
{
|
||||
"from": "res/img",
|
||||
"to": "img"
|
||||
},
|
||||
"webapp/**/*"
|
||||
],
|
||||
"linux": {
|
||||
"target": "deb",
|
||||
"category": "Network;InstantMessaging;Chat",
|
||||
"maintainer": "support@riot.im",
|
||||
"desktop": {
|
||||
"StartupWMClass": "riot"
|
||||
}
|
||||
},
|
||||
"deb": {
|
||||
"afterInstall": "build/linux/after-install.tpl"
|
||||
},
|
||||
"mac": {
|
||||
"category": "public.app-category.social-networking",
|
||||
"darkModeSupport": true
|
||||
},
|
||||
"win": {
|
||||
"target": {
|
||||
"target": "squirrel",
|
||||
"arch": [
|
||||
"x64",
|
||||
"ia32"
|
||||
]
|
||||
},
|
||||
"sign": "scripts/electron_winSign"
|
||||
},
|
||||
"directories": {
|
||||
"output": "dist"
|
||||
},
|
||||
"afterSign": "scripts/electron_afterSign.js"
|
||||
}
|
||||
}
|
15
scripts/check-webapp.js
Executable file
15
scripts/check-webapp.js
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs').promises;
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const webappDir = await fs.opendir('webapp');
|
||||
return 0;
|
||||
} catch (e) {
|
||||
console.log("No 'webapp' directory found. Run 'yarn run fetch' or symlink manually");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
main().then((ret) => process.exit(ret));
|
184
scripts/fetch-package.js
Executable file
184
scripts/fetch-package.js
Executable file
@ -0,0 +1,184 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const process = require('process');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const fsPromises = require('fs').promises;
|
||||
const { https } = require('follow-redirects');
|
||||
const child_process = require('child_process');
|
||||
const tar = require('tar');
|
||||
|
||||
const riotDesktopPackageJson = require('../package.json');
|
||||
|
||||
const PUB_KEY_URL = "https://packages.riot.im/riot-release-key.asc";
|
||||
const PACKAGE_URL_PREFIX = "https://github.com/vector-im/riot-web/releases/download/";
|
||||
|
||||
async function downloadToFile(url, filename) {
|
||||
console.log("Downloading " + url + "...");
|
||||
const outStream = await fs.createWriteStream(filename);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
https.get(url, (resp) => {
|
||||
if (resp.statusCode / 100 !== 2) {
|
||||
reject("Download failed: " + resp.statusCode);
|
||||
return;
|
||||
}
|
||||
|
||||
resp.on('data', (chunk) => {
|
||||
outStream.write(chunk);
|
||||
});
|
||||
resp.on('end', (chunk) => {
|
||||
outStream.end();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}).catch(async (e) => {
|
||||
outStream.end();
|
||||
await fsPromises.unlink(filename);
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
async function verifyFile(filename) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const gpgProc = child_process.execFile('gpg', ['--verify', filename + '.asc', filename], (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
let verify = true;
|
||||
let importkey = false;
|
||||
let pkgDir = 'packages';
|
||||
let deployDir = 'deploys';
|
||||
let targetVersion;
|
||||
|
||||
while (process.argv.length > 2) {
|
||||
switch (process.argv[2]) {
|
||||
case '--noverify':
|
||||
verify = false;
|
||||
break;
|
||||
case '--importkey':
|
||||
importkey = true;
|
||||
break;
|
||||
case '--packages':
|
||||
process.argv.shift();
|
||||
pkgDir = process.argv[2];
|
||||
break;
|
||||
case '--deploys':
|
||||
process.argv.shift();
|
||||
deployDir = process.argv[2];
|
||||
break;
|
||||
default:
|
||||
targetVersion = process.argv[2];
|
||||
}
|
||||
process.argv.shift();
|
||||
}
|
||||
|
||||
if (targetVersion === undefined) {
|
||||
targetVersion = 'v' + riotDesktopPackageJson.version;
|
||||
}
|
||||
|
||||
const haveGpg = await new Promise((resolve) => {
|
||||
child_process.execFile('gpg', ['--version'], (error) => {
|
||||
resolve(!error);
|
||||
});
|
||||
});
|
||||
|
||||
if (importkey) {
|
||||
if (!haveGpg) {
|
||||
console.log("Can't import key without working GPG binary: install GPG and try again");
|
||||
return 1;
|
||||
}
|
||||
|
||||
await new Promise((resolve) => {
|
||||
const gpgProc = child_process.execFile('gpg', ['--import'], (error) => {
|
||||
if (error) {
|
||||
console.log("Failed to import key", error);
|
||||
} else {
|
||||
console.log("Key imported!");
|
||||
}
|
||||
resolve(!error);
|
||||
});
|
||||
https.get(PUB_KEY_URL, (resp) => {
|
||||
resp.on('data', (chunk) => {
|
||||
gpgProc.stdin.write(chunk);
|
||||
});
|
||||
resp.on('end', (chunk) => {
|
||||
gpgProc.stdin.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (verify && !haveGpg) {
|
||||
console.log("No working GPG binary: install GPG or pass --noverify to skip verification");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const haveDeploy = false;
|
||||
const expectedDeployDir = path.join(deployDir, 'riot-' + targetVersion);
|
||||
try {
|
||||
const webappDir = await fs.opendir(expectedDeployDir);
|
||||
console.log(expectedDeployDir + "already exists");
|
||||
haveDeploy = true;
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (!haveDeploy) {
|
||||
const filename = 'riot-' + targetVersion + '.tar.gz';
|
||||
const outPath = path.join(pkgDir, filename);
|
||||
const url = PACKAGE_URL_PREFIX + targetVersion + '/' + filename;
|
||||
try {
|
||||
await fsPromises.stat(outPath);
|
||||
console.log("Already have " + filename + ": not redownloading");
|
||||
} catch (e) {
|
||||
try {
|
||||
await downloadToFile(url, outPath);
|
||||
} catch (e) {
|
||||
console.log("Failed to download " + url, e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (verify) {
|
||||
try {
|
||||
await fsPromises.stat(outPath+'.asc');
|
||||
console.log("Already have " + filename + ".asc: not redownloading");
|
||||
} catch (e) {
|
||||
try {
|
||||
await downloadToFile(url + '.asc', outPath + '.asc');
|
||||
} catch (e) {
|
||||
console.log("Failed to download " + url, e);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await verifyFile(outPath);
|
||||
console.log(outPath + " downloaded and verified");
|
||||
} catch (e) {
|
||||
console.log("Signature verification failed!", e);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
console.log(outPath + " downloaded but NOT verified");
|
||||
}
|
||||
|
||||
await tar.x({
|
||||
file: outPath,
|
||||
cwd: deployDir,
|
||||
});
|
||||
}
|
||||
|
||||
console.log("Symlink " + expectedDeployDir + " -> webapp");
|
||||
// Does this do a sensible thing on Windows?
|
||||
await fsPromises.symlink(expectedDeployDir, 'webapp');
|
||||
}
|
||||
|
||||
main().then((ret) => process.exit(ret));
|
@ -35,7 +35,6 @@ const tray = require('./tray');
|
||||
const vectorMenu = require('./vectormenu');
|
||||
const webContentsHandler = require('./webcontents-handler');
|
||||
const updater = require('./updater');
|
||||
const { migrateFromOldOrigin } = require('./originMigrator');
|
||||
|
||||
const windowStateKeeper = require('electron-window-state');
|
||||
const Store = require('electron-store');
|
||||
@ -64,11 +63,6 @@ if (argv["help"]) {
|
||||
app.exit();
|
||||
}
|
||||
|
||||
// boolean flag set whilst we are doing one-time origin migration
|
||||
// We only serve the origin migration script while we're actually
|
||||
// migrating to mitigate any risk of it being used maliciously.
|
||||
let migratingOrigin = false;
|
||||
|
||||
if (argv['profile-dir']) {
|
||||
app.setPath('userData', argv['profile-dir']);
|
||||
} else if (argv['profile']) {
|
||||
@ -77,7 +71,7 @@ if (argv['profile-dir']) {
|
||||
|
||||
let vectorConfig = {};
|
||||
try {
|
||||
vectorConfig = require('../../webapp/config.json');
|
||||
vectorConfig = require('../webapp/config.json');
|
||||
} catch (e) {
|
||||
// it would be nice to check the error code here and bail if the config
|
||||
// is unparseable, but we get MODULE_NOT_FOUND in the case of a missing
|
||||
@ -231,11 +225,6 @@ ipcMain.on('ipcCall', async function(ev, payload) {
|
||||
mainWindow.focus();
|
||||
}
|
||||
break;
|
||||
case 'origin_migrate':
|
||||
migratingOrigin = true;
|
||||
await migrateFromOldOrigin();
|
||||
migratingOrigin = false;
|
||||
break;
|
||||
case 'getConfig':
|
||||
ret = vectorConfig;
|
||||
break;
|
||||
@ -476,15 +465,8 @@ app.on('ready', () => {
|
||||
}
|
||||
|
||||
let baseDir;
|
||||
// first part of the path determines where we serve from
|
||||
if (migratingOrigin && target[1] === 'origin_migrator_dest') {
|
||||
// the origin migrator destination page
|
||||
// (only the destination script needs to come from the
|
||||
// custom protocol: the source part is loaded from a
|
||||
// file:// as that's the origin we're migrating from).
|
||||
baseDir = __dirname + "/../../origin_migrator/dest";
|
||||
} else if (target[1] === 'webapp') {
|
||||
baseDir = __dirname + "/../../webapp";
|
||||
if (target[1] === 'webapp') {
|
||||
baseDir = path.join(__dirname, "../webapp");
|
||||
} else {
|
||||
callback({error: -6}); // FILE_NOT_FOUND
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user