383 lines
9.8 KiB
JavaScript
383 lines
9.8 KiB
JavaScript
const gulp = require('gulp');
|
|
const path = require('path');
|
|
const os = require('os');
|
|
const fs = require('fs');
|
|
const fse = require('fs-extra');
|
|
const Haxe = require('./haxe');
|
|
const FlashPlayer = require('./flashplayer');
|
|
const debug = require('./debug');
|
|
const webserver = require('gulp-webserver');
|
|
const run = require('../run/index');
|
|
const tail = require('./tail');
|
|
const deb = require('gulp-debian');
|
|
const {BuildSystem, Platform, Config} = require('./core');
|
|
const vfs = require('vinyl-fs');
|
|
const rename = require('gulp-rename');
|
|
const template = require('lodash.template');
|
|
const through = require('through2');
|
|
const Vinyl = require('vinyl');
|
|
|
|
|
|
const streamToPromise = (stream) => {
|
|
return new Promise((resolve, reject) => {
|
|
stream.on("end", resolve);
|
|
stream.on("error", reject);
|
|
});
|
|
};
|
|
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class Target {
|
|
|
|
constructor(config, platform) {
|
|
this.config = config;
|
|
this.platform = platform;
|
|
this.target = 'target';
|
|
}
|
|
|
|
get targetPath() {
|
|
return path.resolve(this.target, this.config.name, this.platform);
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class Builder extends Target {
|
|
|
|
constructor(config, platform, buildSystem, debug) {
|
|
super(config, platform);
|
|
this.buildSystem = buildSystem;
|
|
this.debug = debug;
|
|
}
|
|
|
|
prepare() {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
call() {
|
|
throw 'Not Implemented';
|
|
}
|
|
|
|
static register(buildSystem, builder) {
|
|
Builder.factory[buildSystem] = builder;
|
|
}
|
|
|
|
static new(config, platform, buildSystem, debug) {
|
|
return new Builder.factory[buildSystem](config, platform, buildSystem, debug);
|
|
}
|
|
}
|
|
|
|
Builder.factory = {};
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class HaxeBuilder extends Builder {
|
|
|
|
constructor(config, platform, buildSystem, debug) {
|
|
super(config, platform, buildSystem, debug);
|
|
this.haxe = new Haxe();
|
|
}
|
|
|
|
prepare() {
|
|
let result = this.haxe.prepare().then(() => this.haxe.install(this.config.libs));
|
|
/*if (this.buildSystem === BuildSystem.OPENFL) {
|
|
result = result.then(() => {
|
|
return this.haxe.haxelib(['run', 'openfl', 'setup', this.platform]);
|
|
});
|
|
}*/
|
|
return result;
|
|
}
|
|
|
|
call() {
|
|
const target = this.targetPath;
|
|
switch (this.buildSystem) {
|
|
case BuildSystem.OPENFL:
|
|
return this.haxe.openfl('build', this.platform, this.config, this.debug)
|
|
.then(result => streamToPromise(result.pipe(vfs.dest(target))));
|
|
case BuildSystem.HAXE:
|
|
return this.haxe.build(this.platform, this.config, this.debug)
|
|
.then(result => streamToPromise(result.pipe(vfs.dest(target))));
|
|
}
|
|
}
|
|
}
|
|
|
|
Builder.register(BuildSystem.HAXE, HaxeBuilder);
|
|
Builder.register(BuildSystem.OPENFL, HaxeBuilder);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class Packer extends Target {
|
|
|
|
prepare() {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
call() {
|
|
throw 'Not Implemented';
|
|
}
|
|
|
|
static register(platform, packer) {
|
|
Packer.factory[platform] = packer;
|
|
}
|
|
|
|
static new(config, platform) {
|
|
return new Packer.factory[platform](config);
|
|
}
|
|
}
|
|
|
|
Packer.factory = {};
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class FlashPacker extends Packer {
|
|
|
|
constructor(config) {
|
|
super(config, Platform.FLASH);
|
|
}
|
|
|
|
call() {
|
|
const target = this.targetPath;
|
|
const indexTemplate = template(fs.readFileSync(path.resolve(__dirname, '..', 'template/flash/index.html')));
|
|
const index = indexTemplate(this.config);
|
|
fs.writeFileSync(path.resolve(target, 'index.html'), index);
|
|
fs.copyFileSync(path.resolve(__dirname, '..', 'template/flash/swf.js'), path.resolve(target, 'swf.js'));
|
|
return Promise.resolve();
|
|
}
|
|
}
|
|
|
|
Packer.register(Platform.FLASH, FlashPacker);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class LinuxPacker extends Packer {
|
|
|
|
constructor(config) {
|
|
super(config, Platform.LINUX);
|
|
}
|
|
|
|
call() {
|
|
const target = this.targetPath;
|
|
const buildDir = path.join(os.tmpdir(), 'build', this.config.name, 'debian');
|
|
const desktopTemplate = template(fs.readFileSync(path.resolve(__dirname, '..', 'template/linux/app.desktop')));
|
|
const desktop = desktopTemplate(this.config);
|
|
fse.ensureDirSync(`${buildDir}/usr/share/applications`);
|
|
fs.writeFileSync(`${buildDir}/usr/share/applications/${this.config.meta.filename}.desktop`, desktop);
|
|
fse.copySync(`${target}`, `${buildDir}/usr/share/${this.config.meta.filename}/`);
|
|
return gulp.src(`${buildDir}/*`)
|
|
.pipe(deb({
|
|
package: this.config.meta.filename,
|
|
version: this.config.meta.version,
|
|
section: 'base',
|
|
priority: 'optional',
|
|
architecture: 'all',
|
|
maintainer: this.config.meta.author,
|
|
description: this.config.meta.title,
|
|
changelog: [],
|
|
postinst: [
|
|
'if [ "$1" = "configure" ] && [ -x "`which update-menus 2>/dev/null`" ] ; then\n' +
|
|
' update-menus\n' +
|
|
'fi'
|
|
],
|
|
_target: '/',
|
|
_out: path.join(target, '..', 'debian'),
|
|
_clean: true,
|
|
_verbose: false
|
|
}));
|
|
}
|
|
}
|
|
|
|
Packer.register(Platform.LINUX, LinuxPacker);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class Runner extends Target {
|
|
|
|
constructor(config, platform, debug) {
|
|
super(config, platform);
|
|
this.debug = debug;
|
|
}
|
|
|
|
prepare() {
|
|
return Promise.resolve();
|
|
}
|
|
|
|
call() {
|
|
throw 'Not Implemented';
|
|
}
|
|
|
|
log(stream) {
|
|
return stream
|
|
.pipe(tail(debug.log))
|
|
.pipe(rename('out.log'))
|
|
.pipe(gulp.dest(this.targetPath));
|
|
}
|
|
|
|
static register(platform, runner) {
|
|
Runner.factory[platform] = runner;
|
|
}
|
|
|
|
static new(config, platform, debug) {
|
|
return new Runner.factory[platform](config, debug);
|
|
}
|
|
}
|
|
|
|
Runner.factory = {};
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class FlashRunner extends Runner {
|
|
|
|
constructor(config, debug) {
|
|
super(config, Platform.FLASH, debug);
|
|
this.player = new FlashPlayer(debug);
|
|
}
|
|
|
|
prepare() {
|
|
return this.player.prepare();
|
|
}
|
|
|
|
call() {
|
|
const target = this.targetPath;
|
|
const filename = path.resolve(target, this.config.meta.filename+'.swf');
|
|
const player = this.player.flashPlayerBin;
|
|
FlashPlayer.trust(filename);
|
|
fs.writeFileSync(FlashPlayer.log, '');
|
|
let result = gulp.src(filename)
|
|
.pipe(run(player + " <%=file.basename%>", {cwd: target, verbosity: 0}))
|
|
.pipe(through.obj(function (file, enc, callback) {
|
|
this.push(new Vinyl({path: FlashPlayer.log}));
|
|
callback();
|
|
}));
|
|
return this.log(result);
|
|
}
|
|
}
|
|
|
|
Runner.register(Platform.FLASH, FlashRunner);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class Html5Runner extends Runner {
|
|
|
|
constructor(config, debug) {
|
|
super(config, Platform.HTML5, debug);
|
|
}
|
|
|
|
call() {
|
|
return gulp.src(this.targetPath)
|
|
.pipe(webserver({
|
|
host: 'localhost', port: 3000,
|
|
open: true,
|
|
fallback: 'index.html'
|
|
}));
|
|
}
|
|
}
|
|
|
|
Runner.register(Platform.HTML5, Html5Runner);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class LinuxRunner extends Runner {
|
|
|
|
constructor(config, debug) {
|
|
super(config, Platform.LINUX, debug);
|
|
}
|
|
|
|
call() {
|
|
const target = this.targetPath;
|
|
const filename = path.resolve(target, this.config.meta.filename);
|
|
const result = gulp.src(filename).pipe(run("./<%=file.basename%>", {cwd: target, verbosity: 0}));
|
|
return this.log(result);
|
|
}
|
|
}
|
|
|
|
Runner.register(Platform.LINUX, LinuxRunner);
|
|
Runner.register(Platform.WINDOWS, LinuxRunner); //ToDo:
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class NekoRunner extends Runner {
|
|
|
|
constructor(config, debug) {
|
|
super(config, Platform.NEKO, debug);
|
|
}
|
|
|
|
call() {
|
|
const target = this.targetPath;
|
|
const filename = path.resolve(target, this.config.meta.filename+'.n');
|
|
const result = gulp.src(filename).pipe(run("neko <%=file.path%>", {cwd: target}));
|
|
return this.log(result);
|
|
}
|
|
}
|
|
|
|
Runner.register(Platform.NEKO, NekoRunner);
|
|
|
|
|
|
/**
|
|
*
|
|
*/
|
|
class Project {
|
|
|
|
constructor(buildSystem, platforms, config, prepare) {
|
|
this.buildSystem = buildSystem;
|
|
this.platforms = Array.isArray(platforms) ? platforms : [platforms];
|
|
this.config = config;
|
|
this.prepare = prepare;
|
|
}
|
|
|
|
build(platform, debug) {
|
|
const builder = Builder.new(this.config, platform, this.buildSystem, debug);
|
|
const tasks = [builder.prepare.bind(builder)];
|
|
if (this.prepare) tasks.push(this.prepare);
|
|
tasks.push(builder.call.bind(builder));
|
|
return tasks;
|
|
}
|
|
|
|
run(platform) {
|
|
const runner = Runner.new(this.config, platform, debug);
|
|
return this.build(platform, debug).concat([
|
|
runner.prepare.bind(runner),
|
|
runner.call.bind(runner),
|
|
]);
|
|
}
|
|
|
|
pack(platform) {
|
|
const packer = Packer.new(this.config, platform);
|
|
return [
|
|
packer.prepare.bind(packer),
|
|
packer.call.bind(packer),
|
|
];
|
|
}
|
|
|
|
bind(module, external_gulp /* ToDo: spike */) {
|
|
const _gulp = (external_gulp || gulp);
|
|
for (const platform of this.platforms) {
|
|
module.exports[`${this.config.name}:${platform}:build`] = _gulp.series(this.build(platform));
|
|
module.exports[`${this.config.name}:${platform}:run`] = _gulp.series(this.run(platform));
|
|
if (Packer.factory[platform]) {
|
|
module.exports[`${this.config.name}:${platform}:pack`] = _gulp.series(this.pack(platform));
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
}
|
|
|
|
Project.BuildSystem = BuildSystem;
|
|
Project.Platform = Platform;
|
|
Project.Config = Config;
|
|
Project.Builder = Builder;
|
|
Project.Runner = Runner;
|
|
|
|
|
|
module.exports = Project; |