big update
This commit is contained in:
@@ -27,6 +27,7 @@ class Config {
|
|||||||
this.sources = [];
|
this.sources = [];
|
||||||
this.assets = [];
|
this.assets = [];
|
||||||
this.libs = [];
|
this.libs = [];
|
||||||
|
this.macros = [];
|
||||||
this.meta = {
|
this.meta = {
|
||||||
title: null,
|
title: null,
|
||||||
version: null,
|
version: null,
|
||||||
@@ -46,6 +47,7 @@ class Config {
|
|||||||
if (params.sources !== undefined) this.sources = this.sources.concat(params.sources.map(item => path.resolve(cwd, item)));
|
if (params.sources !== undefined) this.sources = this.sources.concat(params.sources.map(item => path.resolve(cwd, item)));
|
||||||
if (params.assets !== undefined) this.assets = this.assets.concat(params.assets.map(item => path.resolve(cwd, item)));
|
if (params.assets !== undefined) this.assets = this.assets.concat(params.assets.map(item => path.resolve(cwd, item)));
|
||||||
if (params.libs !== undefined) this.libs = this.libs.concat(Array.isArray(params.libs) ? params.libs : Object.entries(params.libs).map(([k, v]) => ({name: k, version: v})));
|
if (params.libs !== undefined) this.libs = this.libs.concat(Array.isArray(params.libs) ? params.libs : Object.entries(params.libs).map(([k, v]) => ({name: k, version: v})));
|
||||||
|
if (params.macros !== undefined) this.macros = this.macros.concat(params.macros);
|
||||||
if (params.meta !== undefined) this.meta = {...this.meta, ...params.meta};
|
if (params.meta !== undefined) this.meta = {...this.meta, ...params.meta};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
const net = require('net');
|
|
||||||
const through = require('through2');
|
|
||||||
const colors = require('ansi-colors');
|
const colors = require('ansi-colors');
|
||||||
const log = require('fancy-log');
|
|
||||||
|
|
||||||
|
|
||||||
const _colors = {
|
const _colors = {
|
||||||
'[DEBUG]': colors.white,
|
'[DEBUG]': colors.white,
|
||||||
'[INFO]': colors.cyan,
|
'[INFO]': colors.cyan,
|
||||||
'[ERROR]': colors.red,
|
'[ERROR]': colors.red,
|
||||||
|
'Called from ': colors.red,
|
||||||
'[WARNING]': colors.yellow,
|
'[WARNING]': colors.yellow,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,58 +21,20 @@ const getColor = (line) => {
|
|||||||
|
|
||||||
class Debug {
|
class Debug {
|
||||||
|
|
||||||
static log (line, color) {
|
constructor() {
|
||||||
if (color === undefined) {
|
this.color = colors.white;
|
||||||
color = getColor(line) || colors.white;
|
this.log = this.log.bind(this);
|
||||||
}
|
}
|
||||||
if (line[0] === '\t') {
|
|
||||||
console.log(color(line));
|
log(line) {
|
||||||
|
const newColor = getColor(line);
|
||||||
|
if (newColor) this.color = newColor;
|
||||||
|
if (line[0] === '\t' || line.startsWith('Called from ')) {
|
||||||
|
console.log(this.color(line));
|
||||||
} else {
|
} else {
|
||||||
const result = line.split(' ');
|
const result = line.split(' ');
|
||||||
console.log(colors.gray(result.slice(0, 4).join(' ')) + ' ' + color(result.slice(4).join(' ')));
|
console.log(colors.gray(result.slice(0, 4).join(' ')) + ' ' + this.color(result.slice(4).join(' ')));
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.host = 'localhost';
|
|
||||||
this.port = 6000 + Math.floor(Math.random() * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
macro() {
|
|
||||||
return [
|
|
||||||
`CompilationOption.set('debug.address','${this.host}')`,
|
|
||||||
`CompilationOption.set('debug.port','${this.port}')`,
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
run() {
|
|
||||||
const debug = this;
|
|
||||||
return through.obj(function (file, enc, callback) {
|
|
||||||
if (this.disabled) {
|
|
||||||
this.emit('end');
|
|
||||||
callback();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let color = colors.white;
|
|
||||||
const server = net.createServer((socket) => {
|
|
||||||
socket.on("data", (data) => {
|
|
||||||
const lines = data.toString().split('\n');
|
|
||||||
for (let line of lines) if (line.length > 2) {
|
|
||||||
const newColor = getColor(line);
|
|
||||||
if (newColor != null) color = newColor;
|
|
||||||
Debug.log(line, color);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
socket.on("close", () => {
|
|
||||||
socket.destroy();
|
|
||||||
server.close();
|
|
||||||
this.emit('end');
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
log(colors.green('[debug]'), colors.cyan('listen on'), colors.magenta(`${debug.host}:${debug.port}`));
|
|
||||||
server.listen(debug.port, debug.host);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ const PluginError = require('plugin-error');
|
|||||||
const colors = require('ansi-colors');
|
const colors = require('ansi-colors');
|
||||||
const log = require('fancy-log');
|
const log = require('fancy-log');
|
||||||
const tar = require('tar');
|
const tar = require('tar');
|
||||||
|
const Vinyl = require('vinyl');
|
||||||
|
|
||||||
|
|
||||||
class FlashPlayer extends Sdk {
|
class FlashPlayer extends Sdk {
|
||||||
@@ -129,10 +130,10 @@ class FlashPlayer extends Sdk {
|
|||||||
//stream.push(file);
|
//stream.push(file);
|
||||||
// ToDo: watch when file is exists
|
// ToDo: watch when file is exists
|
||||||
// or create log file in FlashPlayer.enableLog()?
|
// or create log file in FlashPlayer.enableLog()?
|
||||||
/*stream.push(new Vinyl({
|
stream.push(new Vinyl({
|
||||||
path: FlashPlayer.log
|
path: FlashPlayer.log
|
||||||
}));*/
|
}));
|
||||||
stream.push(file);
|
//stream.push(file);
|
||||||
};
|
};
|
||||||
|
|
||||||
return stream = through.obj(bufferContents);
|
return stream = through.obj(bufferContents);
|
||||||
|
|||||||
102
haxetool/haxe.js
102
haxetool/haxe.js
@@ -56,8 +56,10 @@ class Haxe extends Sdk {
|
|||||||
process.env.HAXE_VERSION = this.version;
|
process.env.HAXE_VERSION = this.version;
|
||||||
process.env.HAXE_STD_PATH = `${this.binPath}/std`;
|
process.env.HAXE_STD_PATH = `${this.binPath}/std`;
|
||||||
process.env.HAXE_HOME = this.binPath;
|
process.env.HAXE_HOME = this.binPath;
|
||||||
|
if (process.env.PATH.indexOf(this.binPath) === -1) {
|
||||||
process.env.PATH = `${process.env.PATH}:${this.binPath}`;
|
process.env.PATH = `${process.env.PATH}:${this.binPath}`;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
prepare() {
|
prepare() {
|
||||||
return super.prepare().then(() => this.activate());
|
return super.prepare().then(() => this.activate());
|
||||||
@@ -81,7 +83,7 @@ class Haxe extends Sdk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openfl(command, platform, config, debug=false) {
|
openfl(command, platform, config, debug=false) {
|
||||||
log(this.tag, colors.cyan('openfl', platform));
|
log(this.tag, colors.cyan(`openfl build ${platform}`));
|
||||||
const buildDir = path.join(os.tmpdir(), 'build', config.name);
|
const buildDir = path.join(os.tmpdir(), 'build', config.name);
|
||||||
mkdirp.sync(buildDir);
|
mkdirp.sync(buildDir);
|
||||||
|
|
||||||
@@ -98,8 +100,33 @@ class Haxe extends Sdk {
|
|||||||
return this.haxelib(args).then(() => vfs.src(`${target}/**/*`));
|
return this.haxelib(args).then(() => vfs.src(`${target}/**/*`));
|
||||||
}
|
}
|
||||||
|
|
||||||
build(platform, config) {
|
build(platform, config, debug=false) {
|
||||||
|
log(this.tag, colors.cyan(`build ${platform}`));
|
||||||
|
const buildDir = path.join(os.tmpdir(), 'build', config.name);
|
||||||
|
mkdirp.sync(buildDir);
|
||||||
|
|
||||||
|
const projectTemplate = template(fs.readFileSync(path.resolve(__dirname, '..', 'template/project.hxml')));
|
||||||
|
|
||||||
|
const ext = {
|
||||||
|
flash: '.swf',
|
||||||
|
neko: '.n',
|
||||||
|
}[platform] || '';
|
||||||
|
|
||||||
|
const out = {
|
||||||
|
flash: 'swf'
|
||||||
|
}[platform] || platform;
|
||||||
|
|
||||||
|
const project = projectTemplate({...config, buildDir: buildDir, platform: platform, ext: ext, out: out});
|
||||||
|
const projectHXML = path.resolve(buildDir, 'project.hxml');
|
||||||
|
fs.writeFileSync(projectHXML, project);
|
||||||
|
|
||||||
|
const args = [projectHXML];
|
||||||
|
if (debug) {
|
||||||
|
args.push('-debug');
|
||||||
|
}
|
||||||
|
const target = path.resolve(buildDir, platform, 'bin');
|
||||||
|
rmdir(target);
|
||||||
|
return this.haxe(args).then(() => vfs.src(`${target}/**/*`));
|
||||||
}
|
}
|
||||||
|
|
||||||
install(packages) {
|
install(packages) {
|
||||||
@@ -151,77 +178,6 @@ class Haxe extends Sdk {
|
|||||||
promise = promise.then(() => this.haxelib(['upgrade', '--always']));
|
promise = promise.then(() => this.haxelib(['upgrade', '--always']));
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_build(params) {
|
|
||||||
params = Object.assign({
|
|
||||||
version: null,
|
|
||||||
values: {},
|
|
||||||
lib: [],
|
|
||||||
macro: [],
|
|
||||||
debug: false,
|
|
||||||
}, params);
|
|
||||||
|
|
||||||
const files = [];
|
|
||||||
let stream = null;
|
|
||||||
|
|
||||||
const bufferContents = (file, enc, callback) => {
|
|
||||||
// ToDo: check file not stream
|
|
||||||
files.push(file);
|
|
||||||
callback();
|
|
||||||
};
|
|
||||||
|
|
||||||
const endStream = (callback) => {
|
|
||||||
log(this.tag, colors.cyan("haxe", params.platform), '=>', colors.magenta(params.outputFile));
|
|
||||||
const args = [];
|
|
||||||
// main
|
|
||||||
args.push('-main', params.main);
|
|
||||||
// lib
|
|
||||||
let lib = params.lib;
|
|
||||||
if (!Array.isArray(lib)) {
|
|
||||||
lib = Object.entries(lib).map(([k, v]) => `${k}:${v.split('@')[0]}`);
|
|
||||||
}
|
|
||||||
for (const item of lib) {
|
|
||||||
args.push('-lib', item);
|
|
||||||
}
|
|
||||||
// cp
|
|
||||||
for (const cp of params.cp) {
|
|
||||||
args.push('-cp', cp);
|
|
||||||
}
|
|
||||||
// macro
|
|
||||||
for (const macro of params.macro) {
|
|
||||||
args.push('--macro', `"${macro}"`);
|
|
||||||
}
|
|
||||||
for (let key of Object.keys(params.values)) {
|
|
||||||
const value = params.values[key];
|
|
||||||
if (value === true) {
|
|
||||||
args.push(`-D ${key}`);
|
|
||||||
} else if (value) {
|
|
||||||
args.push(`-D ${key}="${value}"`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const tmpFile = tmp.generateFile();
|
|
||||||
args.push(`-${params.platform}`, tmpFile.path);
|
|
||||||
if (params.debug) {
|
|
||||||
args.push('-debug');
|
|
||||||
}
|
|
||||||
//console.log('haxe', args.join(' '));
|
|
||||||
this.haxe(args).then(() => {
|
|
||||||
const out = new Vinyl({
|
|
||||||
path: params.outputFile,
|
|
||||||
//contents: fs.createReadStream(tmpFile.path),
|
|
||||||
contents: fs.readFileSync(tmpFile.path),
|
|
||||||
});
|
|
||||||
stream.push(out);
|
|
||||||
callback();
|
|
||||||
}).catch((error) => {
|
|
||||||
stream.emit('error', new PluginError({plugin: this.name, message: error}));
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return stream = through.obj(bufferContents, endStream);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Haxe.ID = 'haxe';
|
Haxe.ID = 'haxe';
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
const exec = require('./exec');
|
|
||||||
const through = require('through2');
|
|
||||||
const PluginError = require('plugin-error');
|
|
||||||
const colors = require('ansi-colors');
|
|
||||||
const log = require('fancy-log');
|
|
||||||
|
|
||||||
class Neko {
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.tag = 'Neko';
|
|
||||||
}
|
|
||||||
|
|
||||||
run(...args) {
|
|
||||||
let stream = null;
|
|
||||||
const bufferContents = (file, enc, callback) => {
|
|
||||||
log(this.tag, colors.cyan("run"), colors.magenta(file.path));
|
|
||||||
|
|
||||||
exec('.', ['neko', file.path].concat(args).join(' '))
|
|
||||||
.then(() => {
|
|
||||||
stream.emit('end');
|
|
||||||
callback();
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
stream.emit('error', new PluginError({plugin: this.tag, message: error}));
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
|
|
||||||
stream.push(file);
|
|
||||||
};
|
|
||||||
|
|
||||||
return stream = through.obj(bufferContents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Neko;
|
|
||||||
@@ -1,28 +1,52 @@
|
|||||||
const gulp = require('gulp');
|
const gulp = require('gulp');
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
//const concat = require('gulp-concat');
|
//const concat = require('gulp-concat');
|
||||||
//const uglify = require('gulp-uglify');
|
//const uglify = require('gulp-uglify');
|
||||||
//const babel = require('gulp-babel');
|
//const babel = require('gulp-babel');
|
||||||
//const template = require('gulp-template');
|
//const template = require('gulp-template');
|
||||||
const Haxe = require('./haxe');
|
const Haxe = require('./haxe');
|
||||||
const FlashPlayer = require('./flashplayer');
|
const FlashPlayer = require('./flashplayer');
|
||||||
const Neko = require('./neko');
|
|
||||||
const Debug = require('./debug');
|
const Debug = require('./debug');
|
||||||
const webserver = require('gulp-webserver');
|
const webserver = require('gulp-webserver');
|
||||||
const run = require('gulp-run');
|
const run = require('../run/index');
|
||||||
const tail = require('./tail');
|
const tail = require('./tail');
|
||||||
//const deb = require('gulp-debian');
|
//const deb = require('gulp-debian');
|
||||||
const {BuildSystem, Platform, Config} = require('./core');
|
const {BuildSystem, Platform, Config} = require('./core');
|
||||||
const vfs = require('vinyl-fs');
|
const vfs = require('vinyl-fs');
|
||||||
|
const rename = require('gulp-rename');
|
||||||
|
|
||||||
|
|
||||||
|
const streamToPromise = (stream) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
stream.on("end", resolve);
|
||||||
|
stream.on("error", reject);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Builder {
|
class Target {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.target = 'target';
|
||||||
|
}
|
||||||
|
|
||||||
|
targetPath(name, platform) {
|
||||||
|
return path.resolve(this.target, name, platform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Builder extends Target {
|
||||||
|
|
||||||
constructor(buildSystem) {
|
constructor(buildSystem) {
|
||||||
|
super();
|
||||||
this.buildSystem = buildSystem;
|
this.buildSystem = buildSystem;
|
||||||
this.target = 'target';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare() {
|
prepare() {
|
||||||
@@ -59,10 +83,14 @@ class HaxeBuilder extends Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
call(platform, config, debug) {
|
call(platform, config, debug) {
|
||||||
|
const target = this.targetPath(config.name, platform);
|
||||||
switch (this.buildSystem) {
|
switch (this.buildSystem) {
|
||||||
case BuildSystem.OPENFL:
|
case BuildSystem.OPENFL:
|
||||||
return this.haxe.openfl('build', platform, config, debug)
|
return this.haxe.openfl('build', platform, config, debug)
|
||||||
.then(result => result.pipe(vfs.dest(`${this.target}/${platform}`)));
|
.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))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,12 +101,12 @@ Builder.register(BuildSystem.OPENFL, HaxeBuilder);
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Runner {
|
class Runner extends Target {
|
||||||
|
|
||||||
constructor(platform, name) {
|
constructor(platform, name) {
|
||||||
|
super();
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.target = 'target';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prepare() {
|
prepare() {
|
||||||
@@ -89,6 +117,17 @@ class Runner {
|
|||||||
throw 'Not Implemented';
|
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) {
|
static register(platform, builder) {
|
||||||
Runner.factory[platform] = builder;
|
Runner.factory[platform] = builder;
|
||||||
}
|
}
|
||||||
@@ -115,9 +154,13 @@ class FlashRunner extends Runner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
call(debug) {
|
call(debug) {
|
||||||
return gulp.src(`${this.target}/${this.platform}/${this.name}.swf`)
|
const target = this.targetPath();
|
||||||
.pipe(this.player.run(true))
|
const filename = path.resolve(target, this.name+'.swf');
|
||||||
.pipe(debug.run());
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +172,7 @@ Runner.register(Platform.FLASH, FlashRunner);
|
|||||||
class Html5Runner extends Runner {
|
class Html5Runner extends Runner {
|
||||||
|
|
||||||
call(debug) {
|
call(debug) {
|
||||||
return gulp.src(`${this.target}/${this.platform}`)
|
return gulp.src(this.targetPath())
|
||||||
.pipe(webserver({
|
.pipe(webserver({
|
||||||
host: 'localhost', port: 3000,
|
host: 'localhost', port: 3000,
|
||||||
open: true,
|
open: true,
|
||||||
@@ -146,9 +189,10 @@ Runner.register(Platform.HTML5, Html5Runner);
|
|||||||
class LinuxRunner extends Runner {
|
class LinuxRunner extends Runner {
|
||||||
|
|
||||||
call(debug) {
|
call(debug) {
|
||||||
return gulp.src(`${this.target}/${this.platform}/${this.name}`)
|
const target = this.targetPath();
|
||||||
.pipe(run(`./${this.name}`, {cwd: `target/${this.platform}`, verbosity: 1}))
|
const filename = path.resolve(target, this.name);
|
||||||
.pipe(tail(Debug.log));
|
const result = gulp.src(filename).pipe(run("./<%=file.basename%>", {cwd: target}));
|
||||||
|
return this.log(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,9 +204,10 @@ Runner.register(Platform.LINUX, LinuxRunner);
|
|||||||
class NekoRunner extends Runner {
|
class NekoRunner extends Runner {
|
||||||
|
|
||||||
call(debug) {
|
call(debug) {
|
||||||
return gulp.src(`${this.target}/${this.platform}/${this.name}.n`)
|
const target = this.targetPath();
|
||||||
.pipe(new Neko().run())
|
const filename = path.resolve(target, this.name+'.n');
|
||||||
.pipe(debug.run());
|
const result = gulp.src(filename).pipe(run("neko <%=file.path%>", {cwd: target}));
|
||||||
|
return this.log(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,10 +245,10 @@ class Project {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
bind(module, gulp /* ToDo: spike */) {
|
bind(module, external_gulp /* ToDo: spike */) {
|
||||||
for (const platform of this.platforms) {
|
for (const platform of this.platforms) {
|
||||||
module.exports[`${this.config.name}:${platform}:build`] = gulp.series(this.build(platform));
|
module.exports[`${this.config.name}:${platform}:build`] = (external_gulp || gulp).series(this.build(platform));
|
||||||
module.exports[`${this.config.name}:${platform}:run`] = gulp.series(this.run(platform));
|
module.exports[`${this.config.name}:${platform}:run`] = (external_gulp || gulp).series(this.run(platform));
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
const through = require('through2');
|
const through = require('through2');
|
||||||
const colors = require('ansi-colors');
|
const {Tail} = require('tail');
|
||||||
const log = require('fancy-log');
|
|
||||||
|
|
||||||
const TAG = colors.green('[tail]');
|
|
||||||
|
|
||||||
|
|
||||||
const {Writable} = require('stream');
|
const {Writable} = require('stream');
|
||||||
const {StringDecoder} = require('string_decoder');
|
const {StringDecoder} = require('string_decoder');
|
||||||
|
|
||||||
|
|
||||||
class StringWritable extends Writable {
|
class StringWritable extends Writable {
|
||||||
|
|
||||||
constructor(handler, options) {
|
constructor(handler, options) {
|
||||||
super(options);
|
super(options);
|
||||||
this.handler = handler;
|
this.handler = handler;
|
||||||
@@ -17,6 +13,7 @@ class StringWritable extends Writable {
|
|||||||
this._decoder = new StringDecoder(state.defaultEncoding);
|
this._decoder = new StringDecoder(state.defaultEncoding);
|
||||||
this.data = '';
|
this.data = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
_write(chunk, encoding, callback) {
|
_write(chunk, encoding, callback) {
|
||||||
if (encoding === 'buffer') {
|
if (encoding === 'buffer') {
|
||||||
chunk = this._decoder.write(chunk);
|
chunk = this._decoder.write(chunk);
|
||||||
@@ -27,6 +24,7 @@ class StringWritable extends Writable {
|
|||||||
this.data += chunk;
|
this.data += chunk;
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
_final(callback) {
|
_final(callback) {
|
||||||
this.data += this._decoder.end();
|
this.data += this._decoder.end();
|
||||||
callback();
|
callback();
|
||||||
@@ -36,7 +34,13 @@ class StringWritable extends Writable {
|
|||||||
|
|
||||||
module.exports = (handler) => {
|
module.exports = (handler) => {
|
||||||
return through.obj(function (file, enc, callback) {
|
return through.obj(function (file, enc, callback) {
|
||||||
|
if (file.contents && file.contents.pipe) {
|
||||||
file.contents.pipe(new StringWritable(handler));
|
file.contents.pipe(new StringWritable(handler));
|
||||||
|
} else {
|
||||||
|
const tail = new Tail(file.path);
|
||||||
|
tail.on("line", data => handler(data));
|
||||||
|
tail.on("error", error => handler('[ERROR]: ', error));
|
||||||
|
}
|
||||||
this.push(file);
|
this.push(file);
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
|
|||||||
1
index.js
1
index.js
@@ -2,7 +2,6 @@ module.exports = {
|
|||||||
Sdk: require('./haxetool/sdk'),
|
Sdk: require('./haxetool/sdk'),
|
||||||
Haxe: require('./haxetool/haxe'),
|
Haxe: require('./haxetool/haxe'),
|
||||||
FlashPlayer: require('./haxetool/flashplayer'),
|
FlashPlayer: require('./haxetool/flashplayer'),
|
||||||
Neko: require('./haxetool/neko'),
|
|
||||||
AdobeAir: require('./haxetool/adobe_air'),
|
AdobeAir: require('./haxetool/adobe_air'),
|
||||||
Project: require('./haxetool/project'),
|
Project: require('./haxetool/project'),
|
||||||
};
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "gulp-haxetool",
|
"name": "gulp-haxetool",
|
||||||
"version": "0.0.5",
|
"version": "0.0.6",
|
||||||
"description": "Haxe tool for gulp",
|
"description": "Haxe tool for gulp",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -10,14 +10,17 @@
|
|||||||
"fs-extra": "^5.0.0",
|
"fs-extra": "^5.0.0",
|
||||||
"got": "^8.3.0",
|
"got": "^8.3.0",
|
||||||
"gulp": "^4.0.0",
|
"gulp": "^4.0.0",
|
||||||
"gulp-run": "^1.7.1",
|
"gulp-rename": "^1.2.2",
|
||||||
|
"gulp-spawn": "^0.4.0",
|
||||||
"gulp-webserver": "^0.9.1",
|
"gulp-webserver": "^0.9.1",
|
||||||
|
"lodash.defaults": "^4.2.0",
|
||||||
"lodash.template": "^4.4.0",
|
"lodash.template": "^4.4.0",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"plugin-error": "^1.0.1",
|
"plugin-error": "^1.0.1",
|
||||||
"progress": "^2.0.0",
|
"progress": "^2.0.0",
|
||||||
"promise-streams": "^2.1.1",
|
"promise-streams": "^2.1.1",
|
||||||
"rmdir": "^1.2.0",
|
"rmdir": "^1.2.0",
|
||||||
|
"tail": "^1.2.3",
|
||||||
"tar": "^4.4.1",
|
"tar": "^4.4.1",
|
||||||
"through2": "^2.0.3",
|
"through2": "^2.0.3",
|
||||||
"tmp-file": "^2.0.1",
|
"tmp-file": "^2.0.1",
|
||||||
|
|||||||
195
run/command.js
Normal file
195
run/command.js
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
var cp = require('child_process');
|
||||||
|
var path = require('path');
|
||||||
|
var stream = require('stream');
|
||||||
|
var util = require('util');
|
||||||
|
var defaults = require('lodash.defaults');
|
||||||
|
var applyTemplate = require('lodash.template');
|
||||||
|
var Vinyl = require('vinyl');
|
||||||
|
var colors = require('ansi-colors');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new `gulp-run` command.
|
||||||
|
*
|
||||||
|
* @param {string} command
|
||||||
|
* @param {object} options
|
||||||
|
*/
|
||||||
|
function Command(command, options) {
|
||||||
|
var previousPath;
|
||||||
|
|
||||||
|
this.command = command;
|
||||||
|
|
||||||
|
// We're on Windows if `process.platform` starts with "win", i.e. "win32".
|
||||||
|
this.isWindows = (process.platform.lastIndexOf('win') === 0);
|
||||||
|
|
||||||
|
// the cwd and environment of the command are the same as the main node
|
||||||
|
// process by default.
|
||||||
|
this.options = defaults(options || {}, {
|
||||||
|
cwd: process.cwd(),
|
||||||
|
env: process.env,
|
||||||
|
verbosity: (options && options.silent) ? 1 : 2,
|
||||||
|
usePowerShell: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// include node_modules/.bin on the path when we execute the command.
|
||||||
|
previousPath = this.options.env.PATH;
|
||||||
|
this.options.env.PATH = path.join(this.options.cwd, 'node_modules', '.bin');
|
||||||
|
this.options.env.PATH += path.delimiter;
|
||||||
|
this.options.env.PATH += previousPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the command, invoking the callback when the command exits.
|
||||||
|
* Returns a Vinyl file wrapping the command's stdout.
|
||||||
|
*
|
||||||
|
* @param {string} stdin
|
||||||
|
* @param {function} callback
|
||||||
|
* @return {Stream}
|
||||||
|
*/
|
||||||
|
Command.prototype.exec = function exec(stdin, callback) {
|
||||||
|
var self = this;
|
||||||
|
var command;
|
||||||
|
var fileName;
|
||||||
|
var directory;
|
||||||
|
var subShell;
|
||||||
|
var log;
|
||||||
|
var err;
|
||||||
|
var stdout;
|
||||||
|
|
||||||
|
// parse the arguments, both are optional.
|
||||||
|
// after parsing, stdin is a vinyl file to use as standard input to
|
||||||
|
// the command (possibly empty), and callback is a function.
|
||||||
|
if (typeof stdin === 'function') {
|
||||||
|
callback = stdin;
|
||||||
|
stdin = undefined;
|
||||||
|
} else if (typeof callback !== 'function') {
|
||||||
|
callback = function noop() {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(stdin instanceof Vinyl)) {
|
||||||
|
fileName = this.command.split(' ')[0];
|
||||||
|
directory = path.join(this.options.cwd, fileName);
|
||||||
|
|
||||||
|
if (typeof stdin === 'string') {
|
||||||
|
stdin = new Vinyl({
|
||||||
|
path: directory,
|
||||||
|
contents: new Buffer(stdin)
|
||||||
|
});
|
||||||
|
} else if (stdin instanceof Buffer || stdin instanceof stream.Readable) {
|
||||||
|
stdin = new Vinyl({
|
||||||
|
path: directory,
|
||||||
|
contents: stdin
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
stdin = new Vinyl(stdin);
|
||||||
|
|
||||||
|
if (!stdin.path) {
|
||||||
|
stdin.path = directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute the command.
|
||||||
|
// we spawn the command in a subshell, so things like i/o redirection
|
||||||
|
// just work. e.g. `echo hello world >> ./hello.txt` works as expected.
|
||||||
|
command = applyTemplate(this.command)({
|
||||||
|
file: stdin
|
||||||
|
});
|
||||||
|
|
||||||
|
if (this.isWindows && this.options.usePowerShell) {
|
||||||
|
// windows powershell
|
||||||
|
subShell = cp.spawn('powershell.exe', ['-NonInteractive', '-NoLogo', '-Command', command], {
|
||||||
|
env: this.options.env,
|
||||||
|
cwd: this.options.cwd
|
||||||
|
});
|
||||||
|
} else if (this.isWindows) {
|
||||||
|
// windows cmd.exe
|
||||||
|
subShell = cp.spawn('cmd.exe', ['/c', command], {
|
||||||
|
env: this.options.env,
|
||||||
|
cwd: this.options.cwd
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// POSIX shell
|
||||||
|
subShell = cp.spawn('sh', ['-c', command], {
|
||||||
|
env: this.options.env,
|
||||||
|
cwd: this.options.cwd
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup the output
|
||||||
|
//
|
||||||
|
// - if verbosity equals to 3, the command prints directly to the terminal.
|
||||||
|
// - if verbosity equals to 2, the command's stdout and stderr are buffered
|
||||||
|
// and printed to the user's terminal after the command exits (this
|
||||||
|
// prevents overlaping output of multiple commands)
|
||||||
|
// - if verbosity equals to 1, the command's stderr is buffered as in 2, but
|
||||||
|
// the stdout is silenced.
|
||||||
|
log = new stream.PassThrough();
|
||||||
|
|
||||||
|
function sendLog(context) {
|
||||||
|
var title = util.format(
|
||||||
|
'$ %s%s',
|
||||||
|
colors.blue(command),
|
||||||
|
(self.options.verbosity < 2) ? colors.grey(' # Silenced\n') : '\n'
|
||||||
|
);
|
||||||
|
|
||||||
|
context.write(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (this.options.verbosity) {
|
||||||
|
case 3:
|
||||||
|
sendLog(process.stdout);
|
||||||
|
subShell.stdout.pipe(process.stdout);
|
||||||
|
subShell.stderr.pipe(process.stderr);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
subShell.stdout.pipe(log);
|
||||||
|
// fallthrough
|
||||||
|
case 1:
|
||||||
|
subShell.stderr.pipe(log);
|
||||||
|
sendLog(log);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup the cleanup proceedure for when the command finishes.
|
||||||
|
subShell.once('close', function handleSubShellClose() {
|
||||||
|
// write the buffered output to stdout
|
||||||
|
var content = log.read();
|
||||||
|
|
||||||
|
if (content !== null) {
|
||||||
|
process.stdout.write(content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
subShell.once('exit', function handleSubShellExit(code) {
|
||||||
|
// report an error if the command exited with a non-zero exit code.
|
||||||
|
if (code !== 0) {
|
||||||
|
err = new Error(util.format('Command `%s` exited with code %s', command, code));
|
||||||
|
err.status = code;
|
||||||
|
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
// the file wrapping stdout is as the one wrapping stdin (same metadata)
|
||||||
|
// with different contents.
|
||||||
|
stdout = stdin.clone();
|
||||||
|
stdout.contents = subShell.stdout.pipe(new stream.PassThrough());
|
||||||
|
|
||||||
|
// finally, write the input to the process's stdin.
|
||||||
|
//stdin.pipe(subShell.stdin); //ToDo:
|
||||||
|
|
||||||
|
return stdout;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the command template.
|
||||||
|
*
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
Command.prototype.toString = function toString() {
|
||||||
|
return this.command;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Command;
|
||||||
70
run/index.js
Normal file
70
run/index.js
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* Pipe shell commands in gulp.
|
||||||
|
* @module gulp-run
|
||||||
|
*/
|
||||||
|
|
||||||
|
var inherit = require('util').inherits;
|
||||||
|
var Transform = require('stream').Transform;
|
||||||
|
var Command = require('./command');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a GulpRunner.
|
||||||
|
*
|
||||||
|
* A GulpRunner is a Vinyl transform stream that spawns a child process to
|
||||||
|
* transform the file. A separate process is spawned to handle each file
|
||||||
|
* passing through the stream.
|
||||||
|
*
|
||||||
|
* @param {string} template
|
||||||
|
* @param {object} options
|
||||||
|
*/
|
||||||
|
function GulpRunner(template, options) {
|
||||||
|
if (!(this instanceof GulpRunner)) {
|
||||||
|
return new GulpRunner(template, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.command = new Command(template, options || {});
|
||||||
|
Transform.call(this, { objectMode: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends {Stream.Transform}
|
||||||
|
*/
|
||||||
|
inherit(GulpRunner, Transform);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} file
|
||||||
|
* @param {string} encoding
|
||||||
|
* @param {function} callback
|
||||||
|
* @return {void}
|
||||||
|
*/
|
||||||
|
GulpRunner.prototype._transform = function _transform(file, encoding, callback) {
|
||||||
|
var newfile = this.command.exec(file, callback);
|
||||||
|
this.push(newfile);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes `stdin` to itself and returns itself.
|
||||||
|
*
|
||||||
|
* Whenever an object is written into the GulpRunner, a new process is
|
||||||
|
* spawned taking that data as standard input, and a Vinyl file wrapping the
|
||||||
|
* process's standard output is pushed downstream.
|
||||||
|
*
|
||||||
|
* `stdin` may be a String, Buffer, Readable stream, or Vinyl file.
|
||||||
|
*
|
||||||
|
* @param {mixed} stdin
|
||||||
|
* @param {function} callback
|
||||||
|
* @return {GulpRunner}
|
||||||
|
*/
|
||||||
|
GulpRunner.prototype.exec = function exec(stdin, callback) {
|
||||||
|
this.write(stdin, callback);
|
||||||
|
this.end();
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @static
|
||||||
|
* @type {Command}
|
||||||
|
*/
|
||||||
|
GulpRunner.Command = Command;
|
||||||
|
|
||||||
|
module.exports = GulpRunner;
|
||||||
9
template/project.hxml
Normal file
9
template/project.hxml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<% sources.forEach(function(item) { %>
|
||||||
|
-cp "<%=item%>"<% }); %>
|
||||||
|
<% libs.forEach(function(item) { %>
|
||||||
|
-lib <%=item.name%>:<%=item.version.split('@').shift()%><% }); %>
|
||||||
|
<% macros.forEach(function(item) { %>
|
||||||
|
--macro "<%=item%>"<% }); %>
|
||||||
|
|
||||||
|
-main <%=main%>
|
||||||
|
-<%=out%> "<%=buildDir%>/<%=platform%>/bin/<%=name%><%=ext%>"
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<project>
|
<project>
|
||||||
<meta title="<%-meta.title%>" package="<%-meta.pack%>" company="<%-meta.company%>"/>
|
<meta title="<%=meta.title%>" package="<%=meta.pack%>" version="<%=meta.version%>" company="<%=meta.company%>"/>
|
||||||
<app main="<%-main%>" path="<%-buildDir%>" file="<%-name%>"/>
|
<app main="<%=main%>" path="<%=buildDir%>" file="<%=name%>"/>
|
||||||
<% sources.forEach(function(item) { %>
|
<% sources.forEach(function(item) { %>
|
||||||
<source path="<%-item%>"/><% }); %>
|
<source path="<%=item%>"/><% }); %>
|
||||||
<% assets.forEach(function(item) { %>
|
<% assets.forEach(function(item) { %>
|
||||||
<assets path="<%-item%>" rename="<%-item.split('/').pop()%>" include="*"/><% }); %>
|
<assets path="<%=item%>" rename="<%=item.split('/').pop()%>" include="*"/><% }); %>
|
||||||
<% libs.forEach(function(item) { %>
|
<% libs.forEach(function(item) { %>
|
||||||
<haxelib name="<%-item.name%>" version="<%-item.version.split('@').shift()%>"/><% }); %>
|
<haxelib name="<%=item.name%>" version="<%=item.version.split('@').shift()%>"/><% }); %>
|
||||||
|
<% macros.forEach(function(item) { %>
|
||||||
|
<haxeflag name="--macro" value="<%=item%>"/><% }); %>
|
||||||
|
|
||||||
<window fps="30"/>
|
<window fps="30"/>
|
||||||
<window width="1024" height="768" unless="html5"/>
|
<window width="1024" height="768" unless="html5"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user