Debian packaging

This commit is contained in:
Samuel Elliott 2019-05-24 22:37:13 +01:00
parent 835cc3134c
commit ff73978485
No known key found for this signature in database
GPG Key ID: 8420C7CDE43DC4D6
16 changed files with 521 additions and 47 deletions

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.parallel('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_${clientpkg.version}-all`, 'release/editor/**/*', '/usr/lib/betterdiscord/editor', 'other/deb/control-editor/**/*', {
VERSION: editorpkg.version
});
});
gulp.task('build-debs', gulp.parallel('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

@ -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"
}
}

124
scripts/dpkg.js Normal file
View File

@ -0,0 +1,124 @@
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 () => {
if (files.length !== 3) throw new Error('Must have three files');
if (!files[0].path.match(/\/debian-binary$/)) throw new Error('Missing debian-binary file');
if (!files[1].path.match(/\/control\.tar(\.gz)?$/)) throw new Error('Missing control archive');
if (!files[2].path.match(/\/data\.tar(\.gz)?$/)) throw new Error('Missing data archive');
const contents = new stream.Readable();
contents._read = () => {};
const debfile = new Vinyl({
cwd: '/',
base: '/',
path: '/' + name,
contents
});
// console.log('Returning deb', debfile, files);
contents.push('!<arch>' + String.fromCharCode(0x0A)); // Signature
for (const [index, file] of files.entries()) {
// console.log(file, index, file.stat);
const size = file.stat ? file.stat.size.toString() : 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")
// stream.write(file.contents);
if (file.isStream()) await new Promise((resolve, reject) => {
file.contents.on('data', data => contents.push(data));
// file.contents.pipe(contents);
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));
}
/**
* 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([
file('debian-binary', '2.0\n', {src: true}),
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),
tar(name + '.tar'),
gzip(),
gulp.dest('release')
])
]),
rename(p => p.basename = p.basename === name ? 'data' : p.basename === name + '.tar' ? 'data.tar' : p.basename),
deb(name + '.deb'),
gulp.dest('release')
]);
}
exports.deb = deb;
exports.mkdeb = mkdeb;