This commit is contained in:
Samuel Elliott 2019-05-28 21:23:40 +00:00 committed by GitHub
commit 6b07efb129
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 631 additions and 65 deletions

View File

@ -11,5 +11,5 @@ indent_size = 4
[*.md]
trim_trailing_whitespace = false
[package.json]
[{package.json,package-lock.json,.travis.yml}]
indent_size = 2

View File

@ -1,13 +1,40 @@
language: node_js
node_js:
- stable
branches:
only:
- master
- 11
addons:
apt:
packages:
- libsecret-1-dev
jobs:
include:
- stage: test
- stage: release
script:
- npm run update_release
- npm run package_release
- npm run build_debs
deploy:
provider: releases
api_key: "$GITHUB_OAUTH_TOKEN"
draft: true
file:
# BetterDiscord installer/updater
- release/releaseinfo.json
- release/core.tar.gz
- release/client.tar.gz
- release/editor.tar.gz
# dpkg
- release/betterdiscord_*.deb
- release/betterdiscord-ptb_*.deb
- release/betterdiscord-canary_*.deb
- release/betterdiscord-core_*.deb
- release/betterdiscord-client_*.deb
- release/betterdiscord-editor_*.deb
file_glob: true
skip_cleanup: true
on:
tags: true

View File

@ -101,4 +101,8 @@ export default new class extends Module {
return this.config.versions.core;
}
get disableUpdater() {
return this.config.disableUpdater;
}
}

View File

@ -98,7 +98,7 @@ export default new class extends Module {
update.text = `${update.id.charAt(0).toUpperCase()}${update.id.slice(1)}`;
update.hint = `Current: ${update.currentVersion} | Latest: ${update.version}`;
update.status = {
update: true,
update: !Globals.disableUpdater.includes(update.id),
updating: false,
updated: false,
error: null
@ -164,7 +164,7 @@ export default new class extends Module {
}
toggleUpdate(update) {
update.status.update = !update.status.update;
update.status.update = !update.status.update && !Globals.disableUpdater.includes(update.id);
}
async startUpdate() {

View File

@ -12,7 +12,8 @@
<div class="bd-settingSwitch">
<div class="bd-title">
<h3>{{item.text}}</h3>
<h3 class="bd-updaterStatus bd-err" v-if="item.status.error">Update Failed!</h3>
<h3 class="bd-updaterStatus" v-if="disabled">Use your package manager to install</h3>
<h3 class="bd-updaterStatus bd-err" v-else-if="item.status.error">Update Failed!</h3>
<h3 class="bd-updaterStatus bd-ok" v-else-if="item.status.updated">Done</h3>
<div class="bd-spinner7" v-else-if="item.status.updating" />
<h3 class="bd-updaterStatus" v-else>Unknown</h3>
@ -23,6 +24,6 @@
<script>
export default {
props: ['item']
props: ['item', 'disabled']
}
</script>

View File

@ -18,15 +18,14 @@
</div>
<div class="bd-formDivider"></div>
<div v-for="update in bdUpdates">
<UpdaterStatus :item="update" v-if="update.status.updating" />
<UpdaterStatus :item="update" :disabled="isDisabled(update)" v-if="update.status.updating || isDisabled(update)" />
<UpdaterToggle :item="update" :toggle="() => updater.toggleUpdate(update)" v-else />
<div class="bd-formDivider"></div>
</div>
</div>
</div>
<div class="bd-formButton bd-button" @click="update">
Update
</div>
<FormButton @click="update" :disabled="!updatesSelected || updating">Update</FormButton>
</div>
</SettingsWrapper>
</template>
@ -37,6 +36,7 @@
import SettingsWrapper from './SettingsWrapper.vue';
import UpdaterToggle from './UpdaterToggle.vue';
import UpdaterStatus from './UpdaterStatus.vue';
import FormButton from '../common/FormButton.vue';
export default {
data() {
@ -49,7 +49,8 @@
components: {
SettingsWrapper,
UpdaterToggle,
UpdaterStatus
UpdaterStatus,
FormButton
},
computed: {
updatesAvailable() {
@ -66,11 +67,20 @@
},
bdUpdates() {
return this.updater.bdUpdates;
},
updatesSelected() {
return this.updater.updates.bd.find(update => update.status.update);
},
updating() {
return this.updater.updates.bd.find(update => update.status.updating);
}
},
methods: {
update() {
this.updater.startUpdate();
},
isDisabled(update) {
return Globals.disableUpdater.includes(update.id);
}
}
}

View File

@ -38,7 +38,10 @@ const TEST_ARGS = () => {
'editor': path.resolve(_basePath, 'editor', 'dist'),
// tmp: path.join(_basePath, 'tmp')
tmp: path.join(os.tmpdir(), 'betterdiscord', `${process.getuid()}`)
}
},
disableUpdater: [
'core', 'client', 'editor'
]
}
}
const TEST_EDITOR = TESTS && true;

View File

@ -66,7 +66,8 @@ export default class Config extends Module {
return {
version: this.version,
versions: this.versions,
paths: this.paths
paths: this.paths,
disableUpdater: this.disableUpdater
};
}
@ -74,4 +75,9 @@ export default class Config extends Module {
compatibility() {
this.args.paths = Object.entries(this.args.paths).map(([id, path]) => ({ id, path }));
}
get disableUpdater() {
return this.args.disableUpdater || (this.args.disableUpdater = []);
}
}

View File

@ -90,6 +90,10 @@ export default class Updater extends Module {
async updateBd(update) {
try {
if (this.bd.config.disableUpdater.includes(update.id)) {
throw {message: `Not installing ${update.id} as updates are disabled. Use your package manager to install updates instead.`};
}
console.log('[BetterDiscord:Updater] Updating', update.id);
await this.downloadTarGz(`https://github.com/JsSucks/BetterDiscordApp${update.remote}`, this.bd.config.getPath('base'));
this.updateFinished(update);
@ -117,6 +121,12 @@ export default class Updater extends Module {
// TODO cleaner
if (bd.length) {
for (const update of bd) {
if (this.bd.config.disableUpdater.includes(update.id)) {
update.error = {message: `Not installing ${update.id} as updates are disabled. Use your package manager to install updates instead.`};
this.bd.sendToDiscord('updater-updateError', update);
continue;
}
try {
await FileUtils.rm(`${this.bd.config.getPath(update.id)}_old`);
// Try to rename dirs first

View File

@ -1,3 +1,5 @@
import path from 'path';
import fs from 'fs';
import gulp from 'gulp';
import pump from 'pump';
import del from 'del';
@ -8,6 +10,7 @@ import replace from 'gulp-replace';
import copydeps from './scripts/copydeps';
import file from 'gulp-file';
import editjson from 'gulp-json-editor';
import {mkdeb} from './scripts/dpkg';
import corepkg from './core/package';
import clientpkg from './client/package';
@ -153,3 +156,50 @@ gulp.task('del-release', function() {
gulp.task('dependencies', gulp.series('node-modules', gulp.parallel('node-sass-bindings', 'keytar-bindings')));
gulp.task('build-release', gulp.parallel('core-release', 'client-release', 'editor-release', 'dependencies'));
gulp.task('release', gulp.series('del-release', 'build-release'));
// Debian packages
gulp.task('build-inject-deb', function () {
const control = fs.readFileSync(path.join(__dirname, 'other', 'deb', 'control', 'control'), 'utf-8');
const version = (control.match(/^Version:\s*(.*)$/m) || [, '1.0.0'])[1];
const arch = (control.match(/^Architecture:\s*(.*)$/m) || [, 'all'])[1];
return mkdeb(`betterdiscord_${version}-${arch}`, 'other/deb/injector/**/*', '/usr/share/discord/resources/app', 'other/deb/control/**/*');
});
gulp.task('build-inject-deb-ptb', function () {
const control = fs.readFileSync(path.join(__dirname, 'other', 'deb', 'control-ptb', 'control'), 'utf-8');
const version = (control.match(/^Version:\s*(.*)$/m) || [, '1.0.0'])[1];
const arch = (control.match(/^Architecture:\s*(.*)$/m) || [, 'all'])[1];
return mkdeb(`betterdiscord-ptb_${version}-${arch}`, 'other/deb/injector/**/*', '/usr/share/discord-ptb/resources/app', 'other/deb/control-ptb/**/*');
});
gulp.task('build-inject-deb-canary', function () {
const control = fs.readFileSync(path.join(__dirname, 'other', 'deb', 'control-canary', 'control'), 'utf-8');
const version = (control.match(/^Version:\s*(.*)$/m) || [, '1.0.0'])[1];
const arch = (control.match(/^Architecture:\s*(.*)$/m) || [, 'all'])[1];
return mkdeb(`betterdiscord-canary_${version}-${arch}`, 'other/deb/injector/**/*', '/usr/share/discord-canary/resources/app', 'other/deb/control-canary/**/*');
});
gulp.task('build-inject-debs', gulp.series('build-inject-deb', 'build-inject-deb-ptb', 'build-inject-deb-canary'));
gulp.task('build-core-deb', function () {
return mkdeb(`betterdiscord-core_${corepkg.version}-all`, 'release/core/**/*', '/usr/lib/betterdiscord/core', 'other/deb/control-core/**/*', {
VERSION: corepkg.version
});
});
gulp.task('build-client-deb', function () {
return mkdeb(`betterdiscord-client_${clientpkg.version}-all`, 'release/client/**/*', '/usr/lib/betterdiscord/client', 'other/deb/control-client/**/*', {
VERSION: clientpkg.version
});
});
gulp.task('build-editor-deb', function () {
return mkdeb(`betterdiscord-editor_${editorpkg.version}-all`, 'release/editor/**/*', '/usr/lib/betterdiscord/editor', 'other/deb/control-editor/**/*', {
VERSION: editorpkg.version
});
});
gulp.task('build-debs', gulp.series('build-inject-debs', 'build-core-deb', 'build-client-deb', 'build-editor-deb'));

View File

@ -0,0 +1 @@
/usr/share/discord-canary/resources/app/bd.json

View File

@ -0,0 +1,6 @@
Package: betterdiscord-canary
Version: 1.0.0
Architecture: all
Maintainer: -
Description: BetterDiscord v2 for Discord Canary
Depends: discord-canary, betterdiscord-core, betterdiscord-client, betterdiscord-editor

View File

@ -0,0 +1,5 @@
Package: betterdiscord-client
Version: ${VERSION}
Architecture: all
Maintainer: -
Description: BetterDiscord v2 client bundle

View File

@ -0,0 +1,6 @@
Package: betterdiscord-core
Version: ${VERSION}
Architecture: all
Maintainer: -
Description: BetterDiscord v2 core files
Depends: libsecret-1-0

View File

@ -0,0 +1,5 @@
Package: betterdiscord-editor
Version: ${VERSION}
Architecture: all
Maintainer: -
Description: BetterDiscord v2 editor bundle

View File

@ -0,0 +1 @@
/usr/share/discord-ptb/resources/app/bd.json

View File

@ -0,0 +1,6 @@
Package: betterdiscord-ptb
Version: 1.0.0
Architecture: all
Maintainer: -
Description: BetterDiscord v2 for Discord PTB
Depends: discord-ptb, betterdiscord-core, betterdiscord-client, betterdiscord-editor

View File

@ -0,0 +1 @@
/usr/share/discord/resources/app/bd.json

View File

@ -0,0 +1,6 @@
Package: betterdiscord
Version: 1.0.0
Architecture: all
Maintainer: -
Description: BetterDiscord v2
Depends: discord, betterdiscord-core, betterdiscord-client, betterdiscord-editor

View File

@ -0,0 +1,19 @@
{
"options": {
"autoInject": true,
"commonCore": true,
"commonData": true
},
"paths": {
"core": "/usr/lib/betterdiscord/core",
"client": "/usr/lib/betterdiscord/client",
"editor": "/usr/lib/betterdiscord/editor",
"data": ".config/betterdiscord/data",
"userconfig": ".config/betterdiscord/bd"
},
"disableUpdater": [
"core",
"client",
"editor"
]
}

View File

@ -0,0 +1,23 @@
const bdinfo = require('./bd');
const { app } = require('electron');
const path = require('path');
const os = require('os');
const Module = require('module');
const packagePath = path.join(__dirname, '..', 'app.asar');
app.getAppPath = () => packagePath;
function loadBd() {
const userconfig = (() => {
try {
return require(path.resolve(os.homedir(), bdinfo.paths.userconfig));
} catch (err) {}
})() || {};
const { BetterDiscord } = require(path.resolve(os.homedir(), (userconfig.paths || {}).core || bdinfo.paths.core));
const instance = new BetterDiscord(bdinfo, userconfig);
}
app.on('ready', loadBd);
Module._load(app.getAppPath(), null, true);

View File

@ -0,0 +1,6 @@
{
"name": "discord",
"description": "Discord Client for Desktop - Bootstrapper",
"main": "index.js",
"private": true
}

297
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "betterdiscord",
"version": "2.0.0-beta.4",
"version": "2.0.0-beta.6",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -1216,6 +1216,12 @@
"integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
"dev": true
},
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
"dev": true
},
"anymatch": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
@ -2008,6 +2014,12 @@
"integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
"dev": true
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
"dev": true
},
"cacache": {
"version": "11.3.2",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz",
@ -5359,6 +5371,32 @@
}
}
},
"gulp-gzip": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/gulp-gzip/-/gulp-gzip-1.4.2.tgz",
"integrity": "sha512-ZIxfkUwk2XmZPTT9pPHrHUQlZMyp9nPhg2sfoeN27mBGpi7OaHnOD+WCN41NXjfJQ69lV1nQ9LLm1hYxx4h3UQ==",
"dev": true,
"requires": {
"ansi-colors": "^1.0.1",
"bytes": "^3.0.0",
"fancy-log": "^1.3.2",
"plugin-error": "^1.0.0",
"stream-to-array": "^2.3.0",
"through2": "^2.0.3"
},
"dependencies": {
"through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
"dev": true,
"requires": {
"readable-stream": "~2.3.6",
"xtend": "~4.0.1"
}
}
}
},
"gulp-inject-string": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/gulp-inject-string/-/gulp-inject-string-1.1.2.tgz",
@ -5410,6 +5448,141 @@
"replacestream": "^4.0.0"
}
},
"gulp-tar": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/gulp-tar/-/gulp-tar-2.1.0.tgz",
"integrity": "sha512-Yp/57bpiZPDVajUJix6QRCpL+XCNNFuaEcDVJ33LzenbGUkpJrH8j+8xJoMNlyi902uXV7rBy5sihwBnu5OfFw==",
"dev": true,
"requires": {
"archiver": "^1.0.0",
"plugin-error": "^0.1.2",
"through2": "^2.0.0",
"vinyl": "^2.1.0"
},
"dependencies": {
"archiver": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz",
"integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=",
"dev": true,
"requires": {
"archiver-utils": "^1.3.0",
"async": "^2.0.0",
"buffer-crc32": "^0.2.1",
"glob": "^7.0.0",
"lodash": "^4.8.0",
"readable-stream": "^2.0.0",
"tar-stream": "^1.5.0",
"walkdir": "^0.0.11",
"zip-stream": "^1.1.0"
}
},
"archiver-utils": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz",
"integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=",
"dev": true,
"requires": {
"glob": "^7.0.0",
"graceful-fs": "^4.1.0",
"lazystream": "^1.0.0",
"lodash": "^4.8.0",
"normalize-path": "^2.0.0",
"readable-stream": "^2.0.0"
}
},
"arr-diff": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz",
"integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=",
"dev": true,
"requires": {
"arr-flatten": "^1.0.1",
"array-slice": "^0.2.3"
}
},
"arr-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz",
"integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=",
"dev": true
},
"array-slice": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
"integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
"dev": true
},
"async": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
"integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
"dev": true,
"requires": {
"lodash": "^4.17.11"
}
},
"extend-shallow": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz",
"integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=",
"dev": true,
"requires": {
"kind-of": "^1.1.0"
}
},
"kind-of": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
"integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
"dev": true
},
"normalize-path": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
"dev": true,
"requires": {
"remove-trailing-separator": "^1.0.1"
}
},
"plugin-error": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz",
"integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=",
"dev": true,
"requires": {
"ansi-cyan": "^0.1.1",
"ansi-red": "^0.1.1",
"arr-diff": "^1.0.1",
"arr-union": "^2.0.1",
"extend-shallow": "^1.1.2"
}
},
"through2": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
"integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
"dev": true,
"requires": {
"readable-stream": "~2.3.6",
"xtend": "~4.0.1"
}
},
"zip-stream": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz",
"integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=",
"dev": true,
"requires": {
"archiver-utils": "^1.3.0",
"compress-commons": "^1.2.0",
"lodash": "^4.8.0",
"readable-stream": "^2.0.0"
}
}
}
},
"gulp-watch": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/gulp-watch/-/gulp-watch-5.0.1.tgz",
@ -7162,6 +7335,12 @@
}
}
},
"merge2": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz",
"integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==",
"dev": true
},
"micromatch": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
@ -8610,6 +8789,57 @@
"requires": {
"speedometer": "~0.1.2",
"through2": "~0.2.3"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
},
"object-keys": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
"integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
"dev": true
},
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
"dev": true
},
"through2": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
"integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
"dev": true,
"requires": {
"readable-stream": "~1.1.9",
"xtend": "~2.1.1"
}
},
"xtend": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
"integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
"dev": true,
"requires": {
"object-keys": "~0.4.0"
}
}
}
},
"promise-inflight": {
@ -10150,6 +10380,15 @@
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
"dev": true
},
"stream-to-array": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz",
"integrity": "sha1-u/azn19D7DC8cbq8s3VXrOzzQ1M=",
"dev": true,
"requires": {
"any-promise": "^1.1.0"
}
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
@ -10499,54 +10738,12 @@
"dev": true
},
"through2": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
"integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz",
"integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==",
"dev": true,
"requires": {
"readable-stream": "~1.1.9",
"xtend": "~2.1.1"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
},
"object-keys": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
"integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
"dev": true
},
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
"dev": true
},
"xtend": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
"integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
"dev": true,
"requires": {
"object-keys": "~0.4.0"
}
}
"readable-stream": "2 || 3"
}
},
"through2-filter": {
@ -11388,6 +11585,12 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true
},
"walkdir": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz",
"integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=",
"dev": true
},
"watchpack": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",

View File

@ -24,7 +24,7 @@
"fs-extra": "^7.0.1",
"keytar": "4.4.1",
"nedb": "^1.8.0",
"node-sass": "^4.11.0",
"node-sass": "4.11.0",
"original-fs": "^1.0.0",
"semver": "^5.6.0",
"tar-fs": "^2.0.0"
@ -51,15 +51,18 @@
"gulp-babel": "^8.0.0",
"gulp-copy": "^4.0.1",
"gulp-file": "^0.4.0",
"gulp-gzip": "^1.4.2",
"gulp-inject-string": "^1.1.2",
"gulp-json-editor": "^2.5.1",
"gulp-rename": "^1.4.0",
"gulp-replace": "^1.0.0",
"gulp-tar": "^2.1.0",
"gulp-watch": "^5.0.1",
"hash-files": "^1.1.1",
"html-webpack-plugin": "^3.2.0",
"jquery": "^3.3.1",
"lodash": "^4.17.11",
"merge2": "^1.2.3",
"mkdirp": "^0.5.1",
"node-gyp": "^3.8.0",
"parallel-webpack": "^2.3.0",
@ -67,6 +70,7 @@
"request-promise-native": "1.0.5",
"sass-lint": "^1.12.1",
"sass-loader": "^7.1.0",
"through2": "^3.0.1",
"v-tooltip": "^2.0.0-rc.33",
"vue": "^2.6.8",
"vue-color": "^2.7.0",
@ -100,6 +104,14 @@
"release": "npm run lint && npm run build_release && gulp release && npm run package_release",
"release_test": "npm run build_release && gulp release",
"update_release": "npm run build_release && gulp release",
"build_inject_deb": "gulp build-inject-deb",
"build_inject-ptb_deb": "gulp build-inject-deb-ptb",
"build_inject-canary_deb": "gulp build-inject-deb-canary",
"build_inject_debs": "gulp build-inject-debs",
"build_core_deb": "gulp build-core-deb",
"build_client_deb": "gulp build-client-deb",
"build_editor_deb": "gulp build-editor-deb",
"build_debs": "gulp build-debs",
"inject": "node scripts/inject.js"
}
}

155
scripts/dpkg.js Normal file
View File

@ -0,0 +1,155 @@
const path = require('path');
const stream = require('stream');
const through2 = require('through2');
const gulp = require('gulp');
const Vinyl = require('vinyl');
const pump = require('pump');
const merge = require('merge2');
const tar = require('gulp-tar');
const gzip = require('gulp-gzip');
const file = require('gulp-file');
const replace = require('gulp-replace');
const rename = require('gulp-rename');
/**
* Return a transform stream that create a Debian package from debian-binary, control.tar and data.tar files.
* @param {string} name The name of the .deb file to create
* @return {stream.TransformStream}
*/
function deb(name) {
const files = [];
return through2({objectMode: true}, (file, enc, callback) => {
files.push(file);
callback(null, file);
}, function (callback) { (async () => {
const orderedfiles = [new Vinyl({path: '/debian-binary', contents: Buffer.from('2.0\n')})];
orderedfiles.push(files.find(f => f.path.match(/\/control\.tar(\.gz)?$/)));
orderedfiles.push(files.find(f => f.path.match(/\/data\.tar(\.gz)?$/)));
if (orderedfiles.length !== 3) throw new Error('Must have three files');
const contents = new stream.Readable();
contents._read = () => {};
const debfile = new Vinyl({
cwd: '/',
base: '/',
path: '/' + name,
contents
});
contents.push('!<arch>' + String.fromCharCode(0x0A)); // Signature
for (const [index, file] of orderedfiles.entries()) {
const size = file.stat && file.stat.size ? file.stat.size : file.contents && file.contents.length ? file.contents.length : 0;
contents.push(rightPaddedWithSpaces(16, path.basename(file.path))); // Filename (ASCII, 16 bytes long)
contents.push(rightPaddedWithSpaces(12, (Math.floor(file.stat ? file.stat.mtime / 1000 : 0)).toString())); // File modification timestamp (Decimal, 12 bytes long)
contents.push(rightPaddedWithSpaces(6, '0')); // Owner ID (Decimal, 6 bytes long)
contents.push(rightPaddedWithSpaces(6, '0')); // Group ID (Decimal, 6 bytes long)
contents.push(rightPaddedWithSpaces(8, '100644')); // File mode (Octal, 8 bytes long)
contents.push(rightPaddedWithSpaces(10, size.toString())); // File size in bytes (Decimal, 10 bytes long)
contents.push(String.fromCharCode(0x60) + String.fromCharCode(0x0A)); // Ending characters ("0x60 0x0A")
if (file.isStream()) await new Promise((resolve, reject) => {
file.contents.on('data', data => contents.push(data));
file.contents.on('end', resolve);
file.contents.on('error', reject);
}); else contents.push(file.contents);
// If the data for an archive member ends at an odd byte offset, then a padding byte with value 0x0A is
// used to position the next archive header on an even byte offset.
if (size % 2 === 1 && index !== 2) {
contents.push(String.fromCharCode(0x0A));
}
}
contents.push(null);
this.push(debfile);
callback();
})().catch(err => {
console.error(err);
callback(err);
}); });
}
function rightPaddedWithSpaces(n, string) {
if (!string) string = '';
if (string.length > n) throw new Error('string is longer than n padding');
return string + (new Array(n - string.length + 1)).join(String.fromCharCode(0x20));
}
function ensuredirectories() {
const directories = [];
return through2.obj(function (file, enc, callback) {
const name = file.relative;
const nameparts = name.split('/');
if (file.isDirectory()) {
if (!directories.includes(file.name)) directories.push(file.name);
} else {
for (let [index, part] of nameparts.slice(0, nameparts.length - 1).entries()) {
let partpath = part;
while (index > 0) {
index--;
partpath = nameparts[index] + '/' + partpath;
}
if (directories.includes(partpath)) continue;
const directory = new Vinyl({
cwd: file.cwd,
base: file.base,
path: path.join(file.base, partpath),
stat: {
isDirectory: () => true
}
});
this.push(directory);
directories.push(partpath);
}
}
callback(null, file);
});
}
/**
* Creates a Debian package.
* @param {string} name
* @param {string} datafiles Path to the data directory
* @param {string} dataprefix The directory the files in the data directory should be unpacked to when installing
* @param {string} controlfiles Path to the control directory
* @param {Object<string, string>} [controlvars] Variables to replace in the control files
* @return {stream.TransformStream}
*/
function mkdeb(name, datafiles, dataprefix, controlfiles, controlvars) {
return pump([
merge([
pump([
gulp.src(controlfiles),
...Object.keys(controlvars || {}).map(k => replace(`\${${k}}`, controlvars[k])),
tar('control.tar'),
gzip()
]),
pump([
gulp.src(datafiles),
rename(p => p.dirname = dataprefix + '/' + p.dirname),
ensuredirectories(),
tar(name + '.tar'),
gzip(),
gulp.dest('release'),
rename(p => p.basename = 'data.tar')
])
]),
deb(name + '.deb'),
gulp.dest('release')
]);
}
exports.deb = deb;
exports.mkdeb = mkdeb;