Files
gulp-haxetool/haxetool/project.js
2018-04-25 15:35:10 +03:00

375 lines
9.3 KiB
JavaScript

const gulp = require('gulp');
const path = require('path');
const os = require('os');
const fs = require('fs');
const fse = require('fs-extra');
//const concat = require('gulp-concat');
//const uglify = require('gulp-uglify');
//const babel = require('gulp-babel');
//const template = require('gulp-template');
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 mkdirp = require('mkdirp');
const streamToPromise = (stream) => {
return new Promise((resolve, reject) => {
stream.on("end", resolve);
stream.on("error", reject);
});
};
/**
*
*/
class Target {
constructor() {
this.target = 'target';
}
targetPath(name, platform) {
return path.resolve(this.target, name, platform);
}
}
/**
*
*/
class Builder extends Target {
constructor(buildSystem) {
super();
this.buildSystem = buildSystem;
}
prepare() {
return Promise.resolve();
}
call(debug) {
throw 'Not Implemented';
}
static register(buildSystem, builder) {
Builder.factory[buildSystem] = builder;
}
static new(buildSystem) {
return new Builder.factory[buildSystem](buildSystem);
}
}
Builder.factory = {};
/**
*
*/
class HaxeBuilder extends Builder {
constructor(buildSystem) {
super(buildSystem);
this.haxe = new Haxe();
}
prepare() {
return this.haxe.prepare();
}
call(platform, config, debug) {
const target = this.targetPath(config.name, platform);
switch (this.buildSystem) {
case BuildSystem.OPENFL:
return this.haxe.openfl('build', platform, config, debug)
.then(result => streamToPromise(result.pipe(vfs.dest(target))));
case BuildSystem.HAXE:
return this.haxe.build(platform, config, debug)
.then(result => streamToPromise(result.pipe(vfs.dest(target))));
}
}
}
Builder.register(BuildSystem.HAXE, HaxeBuilder);
Builder.register(BuildSystem.OPENFL, HaxeBuilder);
/**
*
*/
class Packer extends Target {
constructor(platform) {
super();
this.platform = platform;
}
prepare() {
return Promise.resolve();
}
call(config) {
throw 'Not Implemented';
}
static register(platform, packer) {
Packer.factory[platform] = packer;
}
static new(platform) {
return new Packer.factory[platform]();
}
}
Packer.factory = {};
/**
*
*/
class FlashPacker extends Packer {
constructor() {
super(Platform.FLASH);
}
call(config) {
const target = this.targetPath(config.name, this.platform);
const indexTemplate = template(fs.readFileSync(path.resolve(__dirname, '..', 'template/flash/index.html')));
const index = indexTemplate(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() {
super(Platform.LINUX);
}
call(config) {
const target = this.targetPath(config.name, this.platform);
const buildDir = path.join(os.tmpdir(), 'build', config.name, 'debian');
const desktopTemplate = template(fs.readFileSync(path.resolve(__dirname, '..', 'template/linux/app.desktop')));
const desktop = desktopTemplate(config);
mkdirp.sync(`${buildDir}/usr/share/applications`);
fs.writeFileSync(`${buildDir}/usr/share/applications/${config.meta.filename}.desktop`, desktop);
fse.copySync(`${target}`, `${buildDir}/usr/share/${config.meta.filename}/`);
return gulp.src(`${buildDir}/*`)
.pipe(deb({
package: config.meta.filename,
version: config.meta.version,
section: 'base',
priority: 'optional',
architecture: 'all',
maintainer: config.meta.author,
description: 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(platform, name) {
super();
this.platform = platform;
this.name = name;
}
prepare() {
return Promise.resolve();
}
call(debug) {
throw 'Not Implemented';
}
targetPath() {
return super.targetPath(this.name, this.platform);
}
log(stream) {
stream
.pipe(tail(new Debug().log))
.pipe(rename('out.log'))
.pipe(gulp.dest(this.targetPath()));
}
static register(platform, builder) {
Runner.factory[platform] = builder;
}
static new(platform, name) {
return new Runner.factory[platform](platform, name);
}
}
Runner.factory = {};
/**
*
*/
class FlashRunner extends Runner {
constructor(platform, name) {
super(platform, name);
this.player = new FlashPlayer();
}
prepare() {
return this.player.prepare();
}
call(debug) {
const target = this.targetPath();
const filename = path.resolve(target, this.name+'.swf');
const player = this.player.flashPlayerBin(debug);
FlashPlayer.trust(filename);
fs.writeFileSync(FlashPlayer.log, '');
const result = gulp.src(filename).pipe(run(player + " <%=file.basename%>", {cwd: target}));
return this.log(gulp.src(FlashPlayer.log));
}
}
Runner.register(Platform.FLASH, FlashRunner);
/**
*
*/
class Html5Runner extends Runner {
call(debug) {
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 {
call(debug) {
const target = this.targetPath();
const filename = path.resolve(target, this.name);
const result = gulp.src(filename).pipe(run("./<%=file.basename%>", {cwd: target}));
return this.log(result);
}
}
Runner.register(Platform.LINUX, LinuxRunner);
/**
*
*/
class NekoRunner extends Runner {
call(debug) {
const target = this.targetPath();
const filename = path.resolve(target, this.name+'.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) {
this.buildSystem = buildSystem;
this.platforms = platforms;
this.config = config;
}
build(platform) {
const builder = Builder.new(this.buildSystem);
const config = this.config;
return [
function prepare() { return builder.prepare() },
function build() { return builder.call(platform, config) },
];
}
run(platform) {
const builder = Builder.new(this.buildSystem);
const runner = Runner.new(platform, this.config.name);
const config = this.config;
const debug = new Debug();
return [
function prepare() { return builder.prepare() },
function build() { return builder.call(platform, config, debug) },
function prepare() { return runner.prepare() },
function run() { return runner.call(debug) },
];
}
pack(platform) {
const config = this.config;
const packer = Packer.new(platform);
return [
function prepare() { return packer.prepare() },
function pack() { return packer.call(config) },
];
}
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, _gulp));
}
}
return this;
}
}
Project.BuildSystem = BuildSystem;
Project.Platform = Platform;
Project.Config = Config;
Project.Builder = Builder;
Project.Runner = Runner;
module.exports = Project;