4 Commits

Author SHA1 Message Date
961766a37c 0.2.0 2026-05-15 22:27:22 +03:00
ca61b68cd9 feat(ruffle): add alternative ruffle flash target runner 2026-05-15 22:27:10 +03:00
715f6807d8 feat(android): up android sdk version 2021-05-24 22:02:00 +03:00
e0eddbcab5 [template] add flags to project.hxml template 2020-03-30 18:58:01 +03:00
13 changed files with 179 additions and 78 deletions

6
.editorconfig Normal file
View File

@@ -0,0 +1,6 @@
root = true
[*]
indent_style = space
indent_size = 4
max_line_length = 120

View File

@@ -1,51 +1,29 @@
0.1.6 ## v0.2.0 (2026-05-15)
-----
* Android: fix build result apk path
0.1.5 ### Feat
-----
* Haxe: default version 4.0.5
0.1.4 - **ruffle**: add alternative ruffle flash target runner
-----
* Config: android extensions params
0.1.3 ## 0.1.9 (2021-05-24)
-----
* Android: installed packages list
* Haxe: buildDir static property
0.1.2 ### Feat
-----
* Haxe: move build dir from tmp to project dir
0.1.1 - **android**: up android sdk version
-----
* Android sign apk (config.key.store and config.key.pass params)
0.1.0 ## 0.1.8 (2020-03-30)
------
* Android build
* Windows build
* Windows innosetup packer
0.0.18 ## 0.1.7 (2020-03-25)
------
* Add meta.fps project param
0.0.12 ## 0.1.6 (2020-02-19)
-----
* Openfl android platform support
* Android sdk module
0.0.11 ## 0.1.5 (2020-02-18)
------
* Added Neko module
* FlashPlayer output with stream
* Verbose output mode (--verbose)
0.0.10 ## 0.1.0 (2019-09-03)
------
* Windows compatibility ## 0.0.18 (2019-05-20)
* Change FlashPlayer download link
* Use 'fs-extra' without 'mkdirp' and 'rmdir' ## 0.0.17 (2019-03-28)
## 0.0.16 (2019-03-14)
## 0.0.15 (2019-03-14)

View File

@@ -12,27 +12,22 @@ const Env = require('./env');
class Android extends Sdk { class Android extends Sdk {
constructor(version) { constructor(version, ndkVersion) {
super(Android.ID, version || Android.VERSION); super(Android.ID, version || Android.VERSION);
this.ndk_version = 'r15c'; this.ndk_version = ndkVersion || Android.NDK_VERSION;
this.repository = 'https://dl.google.com/android/repository';
} }
get prepared() { get prepared() {
try { try {
return fs.existsSync(`${this.path}/tools/bin/sdkmanager`); return fs.existsSync(this.sdkmanager_bin);
} catch (e) { } catch (e) {
return false; return false;
} }
} }
get link() { get link() {
const system = System.isWindows ? 'windows' : System.isLinux ? 'linux' : null; return `${this.repository}/commandlinetools-${System.os}-${this.version}_latest.zip`;
if (!system) throw 'Unsupported system';
if (this.version.indexOf('.') > -1) {
return `https://dl.google.com/android/repository/tools_r${this.version}-${system}.zip`;
} else {
return `https://dl.google.com/android/repository/sdk-tools-${system}-${this.version}.zip`;
}
} }
get android_home() { get android_home() {
@@ -43,6 +38,10 @@ class Android extends Sdk {
return path.join(this.path, 'ndk-bundle') return path.join(this.path, 'ndk-bundle')
} }
get sdkmanager_bin() {
return path.join(this.path, 'cmdline-tools/bin/sdkmanager');
}
prepare() { prepare() {
const result = []; const result = [];
result.push(super.prepare(0)); result.push(super.prepare(0));
@@ -54,7 +53,7 @@ class Android extends Sdk {
prepare_ndk() { prepare_ndk() {
// ToDo: support windows // ToDo: support windows
const url = `https://dl.google.com/android/repository/android-ndk-${this.ndk_version}-linux-x86_64.zip`; const url = `${this.repository}/android-ndk-${this.ndk_version}-${System.os}-x86_64.zip`;
this.log.d('download: *%s*', url); this.log.d('download: *%s*', url);
return Sdk.Downloader.download(url, this.ndk_home, 1, true); return Sdk.Downloader.download(url, this.ndk_home, 1, true);
} }
@@ -76,12 +75,15 @@ class Android extends Sdk {
if (install.size === 0) { if (install.size === 0) {
return Promise.resolve(); return Promise.resolve();
} }
const androidBin = path.join(this.path, 'tools/bin/sdkmanager'); const sdkmanagerBin = this.sdkmanager_bin;
if (fs.existsSync(androidBin)) { if (fs.existsSync(sdkmanagerBin)) {
fs.chmodSync(androidBin, 0o755); fs.chmodSync(sdkmanagerBin, 0o755);
} }
const yes = '(while sleep 3; do echo "y"; done)'; const yes = '(while sleep 3; do echo "y"; done)';
const command = [yes, '|', androidBin].concat(Array.from(install).map(name => `"${name}"`)).join(' '); const command = [yes, '|', sdkmanagerBin]
.concat(Array.from(install).map(name => `"${name}"`))
.concat([`--sdk_root="${this.path}"`])
.join(' ');
return exec('.', command).then(() => { return exec('.', command).then(() => {
for (const key of install) { for (const key of install) {
installed.add(key); installed.add(key);
@@ -180,8 +182,11 @@ class Android extends Sdk {
const self = this; const self = this;
return through.obj(function(file, enc, callback) { return through.obj(function(file, enc, callback) {
self._installApk(file.path, file.package).then(() => { self._installApk(file.path, file.package).then(() => {
// ToDo: kludge: delay before start
setTimeout(() => {
this.push(file); this.push(file);
callback(); callback();
}, 500);
}); });
}); });
} }
@@ -242,10 +247,10 @@ class Android extends Sdk {
Android.ID = 'android'; Android.ID = 'android';
Android.VERSION_25_2_3 = '25.2.3'; Android.VERSION_7302050 = '7302050';
Android.VERSION_3859397 = '3859397'; Android.VERSION = Android.VERSION_7302050;
Android.VERSION_4333796 = '4333796';
Android.VERSION = Android.VERSION_4333796; Android.NDK_VERSION_R15C = 'r15c';
Android.NDK_VERSION = Android.NDK_VERSION_R15C;
module.exports = Android; module.exports = Android;

View File

@@ -78,7 +78,7 @@ class Config {
afterUpdate() { afterUpdate() {
if (this.meta.mobileWidth === null) this.meta.mobileWidth = this.meta.width; if (this.meta.mobileWidth === null) this.meta.mobileWidth = this.meta.width;
if (this.meta.mobileHeight === null) this.meta.mobileHeight = Math.round(this.meta.mobileWidth / 1.777777778); if (this.meta.mobileHeight === null) this.meta.mobileHeight = Math.round(this.meta.mobileWidth / 2.222222222);
} }
branch(params) { branch(params) {

View File

@@ -5,15 +5,18 @@ const os = require('os');
const through = require('through2'); const through = require('through2');
const Sdk = require('./sdk'); const Sdk = require('./sdk');
const System = require('./system'); const System = require('./system');
const Env = require('./env');
const run = require('../run/index'); const run = require('../run/index');
const {TailVinyl} = require('./tail'); const {TailVinyl} = require('./tail');
class FlashPlayer extends Sdk { class FlashPlayer extends Sdk {
BASE_URL = 'https://fpdownload.macromedia.com/pub/flashplayer/updaters';
constructor(debug, version) { constructor(debug, version, playerId = FlashPlayer.ID) {
super(FlashPlayer.ID, version || FlashPlayer.VERSION); super(playerId, version || FlashPlayer.VERSION);
this.debug = debug; this.debug = debug;
this.baseUrl = Env.get('FLASHPLAYER_URL') || this.BASE_URL;
} }
prepare() { prepare() {
@@ -29,22 +32,22 @@ class FlashPlayer extends Sdk {
} }
get link() { get link() {
const baseUrl = `https://fpdownload.macromedia.com/pub/flashplayer/updaters/${this.version}/`; const baseUrl = `${this.baseUrl}/${this.version}`;
if (System.isWindows) { if (System.isWindows) {
return baseUrl + `flashplayer_${this.version}_sa${this.debug ? '_debug' : ''}.exe`; return this.baseUrl + `/flashplayer_${this.version}_sa${this.debug ? '_debug' : ''}.exe`;
} else if (System.isLinux) { } else if (System.isLinux) {
return baseUrl + `flash_player_sa_linux${this.debug ? '_debug' : ''}.x86_64.tar.gz`; return this.baseUrl + `/flash_player_sa_linux${this.debug ? '_debug' : ''}.x86_64.tar.gz`;
} else { } else {
throw `Unsupported os '${os.type()}'`; throw `Unsupported os '${os.type()}'`;
} }
} }
get flashPlayerBin() { get flashPlayerBin() {
if (os.type() === 'Windows_NT') { if (System.isWindows) {
const v = this.version.split('.'); const v = this.version.split('.');
const playerName = `flashplayer_${this.version}_sa${this.debug ? '_debug' : ''}.exe`; const playerName = `flashplayer_${this.version}_sa${this.debug ? '_debug' : ''}.exe`;
return path.join(this.path, playerName); return path.join(this.path, playerName);
} else if (os.type() === 'Linux') { } else if (System.isLinux) {
const binPath = path.join(this.path, `flashplayer${this.debug ? 'debugger' : ''}`); const binPath = path.join(this.path, `flashplayer${this.debug ? 'debugger' : ''}`);
fs.chmodSync(binPath, 0o755); fs.chmodSync(binPath, 0o755);
return binPath; return binPath;

View File

@@ -5,6 +5,7 @@ const fs = require('fs');
const fse = require('fs-extra'); const fse = require('fs-extra');
const Haxe = require('./haxe'); const Haxe = require('./haxe');
const FlashPlayer = require('./flashplayer'); const FlashPlayer = require('./flashplayer');
const RufflePlayer = require('./ruffle');
const Android = require('./android'); const Android = require('./android');
const Neko = require('./neko'); const Neko = require('./neko');
const InnoSetup = require('./innosetup'); const InnoSetup = require('./innosetup');
@@ -106,7 +107,7 @@ class HaxeBuilder extends Builder {
'build-tools;27.0.3', 'build-tools;27.0.3',
'platforms;android-28', //ToDo: lime version 7.6.0 -> 28; 7.0.0 -> 26 'platforms;android-28', //ToDo: lime version 7.6.0 -> 28; 7.0.0 -> 26
//'ndk-bundle', //'ndk-bundle',
'lldb;3.1', //'lldb;3.1',
'cmake;3.6.4111459', 'cmake;3.6.4111459',
])); ]));
const AndroidSDK = this.android.android_home; const AndroidSDK = this.android.android_home;
@@ -332,9 +333,9 @@ Runner.factory = {};
*/ */
class FlashRunner extends Runner { class FlashRunner extends Runner {
constructor(config, debug) { constructor(config, debug, player = FlashPlayer) {
super(config, Platform.FLASH, debug); super(config, Platform.FLASH, debug);
this.player = new FlashPlayer(debug); this.player = new player(debug);
} }
prepare() { prepare() {
@@ -349,6 +350,12 @@ class FlashRunner extends Runner {
} }
} }
class RuffleRunner extends FlashRunner {
constructor(config, debug) {
super(config, debug, RufflePlayer);
}
}
Runner.register(Platform.FLASH, FlashRunner); Runner.register(Platform.FLASH, FlashRunner);
/** /**
@@ -532,6 +539,10 @@ class Project {
} }
return this; return this;
} }
static useRuffle() {
Runner.register(Platform.FLASH, RuffleRunner);
}
} }
Project.BuildSystem = BuildSystem; Project.BuildSystem = BuildSystem;

75
haxetool/ruffle.js Executable file
View File

@@ -0,0 +1,75 @@
const path = require("path");
const fs = require("fs");
const fse = require("fs-extra");
const os = require("os");
const through = require("through2");
const Sdk = require("./sdk");
const System = require("./system");
const Env = require('./env');
const run = require("../run/index");
const { TailVinyl } = require("./tail");
const FlashPlayer = require("./flashplayer");
class RufflePlayer extends FlashPlayer {
BASE_URL = 'https://github.com/ruffle-rs/ruffle/releases/download';
constructor(debug, version) {
super(debug, version || RufflePlayer.VERSION, RufflePlayer.ID);
this.debug = debug;
this.baseUrl = Env.get('RUFFLE_URL') || this.BASE_URL;
}
get link() {
const baseUrl = `${baseUrl}/${this.version.replaceAll('_', '-')}`;
if (System.isWindows) {
return baseUrl + `/ruffle-${this.version}-windows-x86_64.zip`;
} else if (System.isLinux) {
return baseUrl + `/ruffle-${this.version}-linux-x86_64.tar.gz`;
} else {
throw `Unsupported os '${os.type()}'`;
}
}
get flashPlayerBin() {
if (System.isWindows) {
return path.join(this.path, "ruffle.exe");
} else if (System.isLinux) {
return path.join(this.path, "ruffle");
} else {
throw `Unsupported os '${os.type()}'`;
}
}
static get log() {
return path.join(os.homedir(), ".cache/ruffle/log/ruffle.log");
}
run(filename, params) {
this.log.i("_run_ *%s*", filename);
return run(`${this.flashPlayerBin} ${filename}`, params)
.exec()
.pipe(
through.obj(function (file, enc, callback) {
const log = new TailVinyl({
path: RufflePlayer.log,
handler: (line) => {
if (line.includes("avm_trace")) {
return line.split("avm_trace: ").pop();
}
},
});
this.on("end", () => log.dispose());
this.push(log);
callback();
}),
);
}
}
RufflePlayer.ID = "ruffle";
RufflePlayer.VERSION_2026_05_15 = "nightly-2026_05_15";
RufflePlayer.VERSION = RufflePlayer.VERSION_2026_05_15;
module.exports = RufflePlayer;

View File

@@ -55,6 +55,11 @@ class Downloader {
if (entry.type === 'Directory') { if (entry.type === 'Directory') {
fse.ensureDirSync(path.join(dest, path.normalize(filePath))); fse.ensureDirSync(path.join(dest, path.normalize(filePath)));
} else if (entry.type === 'File') { } else if (entry.type === 'File') {
const fullFilePath = path.join(dest, path.normalize(filePath));
const dirPath = path.dirname(fullFilePath);
if (!fs.existsSync(dirPath)) {
fse.ensureDirSync(dirPath);
}
entry.pipe(fs.createWriteStream(path.join(dest, path.normalize(filePath)), { entry.pipe(fs.createWriteStream(path.join(dest, path.normalize(filePath)), {
// ToDo: zip entry file mode? // ToDo: zip entry file mode?
mode: executable ? 0o755 : undefined, mode: executable ? 0o755 : undefined,
@@ -118,7 +123,7 @@ class Sdk {
if (this.prepared) { if (this.prepared) {
return Promise.resolve(); return Promise.resolve();
} else { } else {
this.log.d('download: *%s*', this.link); this.log.i('download: *%s*', this.link);
return Downloader.download(this.link, this.path, strip); return Downloader.download(this.link, this.path, strip);
} }
} }

View File

@@ -10,6 +10,14 @@ class System {
return os.type() === 'Linux'; return os.type() === 'Linux';
} }
static get os() {
return (
this.isWindows ? 'windows' :
this.isLinux ? 'linux' :
undefined
);
}
static get archInt() { static get archInt() {
if (os.arch() === 'ia32') return 32; if (os.arch() === 'ia32') return 32;
if (os.arch() === 'x64') return 64; if (os.arch() === 'x64') return 64;

View File

@@ -13,7 +13,14 @@ class TailVinyl extends Vinyl {
super(params); super(params);
if (params.path) { if (params.path) {
this.tail = new Tail(params.path); this.tail = new Tail(params.path);
this.tail.on('line', data => this.contents.write(data + '\n')); this.tail.on('line', line => {
if (params.handler) {
line = params.handler(line);
}
if (line) {
this.contents.write(line + '\n');
}
}),
this.tail.on('error', error => this.contents.write('error: ' + error)); this.tail.on('error', error => this.contents.write('error: ' + error));
} }
} }

View File

@@ -3,6 +3,7 @@ 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'),
RufflePlayer: require('./haxetool/ruffle'),
Android: require('./haxetool/android'), Android: require('./haxetool/android'),
AdobeAir: require('./haxetool/adobe_air'), AdobeAir: require('./haxetool/adobe_air'),
Project: require('./haxetool/project'), Project: require('./haxetool/project'),

View File

@@ -1,6 +1,6 @@
{ {
"name": "gulp-haxetool", "name": "gulp-haxetool",
"version": "0.1.7", "version": "0.2.0",
"description": "HaXe Tool for Gulp", "description": "HaXe Tool for Gulp",
"main": "index.js", "main": "index.js",
"dependencies": { "dependencies": {
@@ -35,7 +35,7 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+ssh://git@bitbucket.org/shmyga/gulp-haxetool.git" "url": "https://git.shmyga.ru/InfernalGames/gulp-haxetool.git"
}, },
"keywords": [ "keywords": [
"gulp", "gulp",
@@ -43,5 +43,5 @@
], ],
"author": "shmyga", "author": "shmyga",
"license": "ISC", "license": "ISC",
"homepage": "https://bitbucket.org/shmyga/gulp-haxetool#readme" "homepage": "https://git.shmyga.ru/InfernalGames/gulp-haxetool#readme"
} }

View File

@@ -4,6 +4,8 @@
-lib <%=item.name%>:<%=item.version.split('@').shift()%><% }); %> -lib <%=item.name%>:<%=item.version.split('@').shift()%><% }); %>
<% macros.forEach(function(item) { %> <% macros.forEach(function(item) { %>
--macro "<%=item%>"<% }); %> --macro "<%=item%>"<% }); %>
<% flags.forEach(function(item) { %>
-D <%=item%><% }); %>
-main <%=main%> -main <%=main%>
-<%=out%> "<%=buildDir%>/<%=platform%>/bin/<%=meta.filename%><%=ext%>" -<%=out%> "<%=buildDir%>/<%=platform%>/bin/<%=meta.filename%><%=ext%>"