From 4ec83c363827d22969972a3dda633ba4c3841496 Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Fri, 3 Aug 2018 16:38:50 -0700 Subject: [PATCH] Add lime.tools.* and keep Project-based tool code --- src/lime/tools/AIRHelper.hx | 361 ++++ src/lime/tools/AndroidHelper.hx | 479 +++++ src/lime/tools/ApplicationData.hx | 14 + src/lime/tools/Architecture.hx | 16 + src/lime/tools/Asset.hx | 146 ++ src/lime/tools/AssetEncoding.hx | 9 + src/lime/tools/AssetHelper.hx | 832 ++++++++ src/lime/tools/AssetType.hx | 15 + src/lime/tools/CLICommand.hx | 20 + src/lime/tools/CLIHelper.hx | 111 + src/lime/tools/CPPHelper.hx | 331 +++ src/lime/tools/CSHelper.hx | 302 +++ src/lime/tools/Command.hx | 18 + src/lime/tools/CommandHelper.hx | 57 + src/lime/tools/ConfigData.hx | 655 ++++++ src/lime/tools/ConfigHelper.hx | 397 ++++ src/lime/tools/Dependency.hx | 31 + src/lime/tools/DeploymentHelper.hx | 45 + src/lime/tools/ElectronHelper.hx | 31 + src/lime/tools/FlashHelper.hx | 1059 ++++++++++ src/lime/tools/HTML5Helper.hx | 270 +++ src/lime/tools/HXProject.hx | 1582 ++++++++++++++ src/lime/tools/IOSHelper.hx | 448 ++++ src/lime/tools/Icon.hx | 33 + src/lime/tools/IconHelper.hx | 461 +++++ src/lime/tools/ImageHelper.hx | 152 ++ src/lime/tools/JavaHelper.hx | 18 + src/lime/tools/Keystore.hx | 40 + src/lime/tools/Library.hx | 49 + src/lime/tools/MetaData.hx | 15 + src/lime/tools/ModuleData.hx | 57 + src/lime/tools/ModuleHelper.hx | 726 +++++++ src/lime/tools/NekoHelper.hx | 85 + src/lime/tools/NodeJSHelper.hx | 62 + src/lime/tools/Orientation.hx | 11 + src/lime/tools/Platform.hx | 28 + src/lime/tools/PlatformTarget.hx | 179 ++ src/lime/tools/PlatformTargetMain.hx | 176 ++ src/lime/tools/PlatformType.hx | 11 + src/lime/tools/Project.hx | 1601 ++++++++++++++ src/lime/tools/ProjectHelper.hx | 231 +++ src/lime/tools/ProjectXMLParser.hx | 2301 +++++++++++++++++++++ src/lime/tools/SplashScreen.hx | 32 + src/lime/tools/TVOSHelper.hx | 454 ++++ src/lime/tools/TizenHelper.hx | 229 ++ src/lime/tools/WindowData.hx | 36 + src/lime/tools/XCodeHelper.hx | 149 ++ tools/CommandLineTools.hx | 425 ++-- tools/RunScript.hx | 254 +-- tools/SVGExport.hx | 170 +- tools/platforms/AIRPlatform.hx | 55 +- tools/platforms/AndroidPlatform.hx | 67 +- tools/platforms/EmscriptenPlatform.hx | 52 +- tools/platforms/FlashPlatform.hx | 55 +- tools/platforms/HTML5Platform.hx | 69 +- tools/platforms/IOSPlatform.hx | 87 +- tools/platforms/LinuxPlatform.hx | 78 +- tools/platforms/MacPlatform.hx | 89 +- tools/platforms/TVOSPlatform.hx | 91 +- tools/platforms/TizenPlatform.hx | 48 +- tools/platforms/WindowsPlatform.hx | 113 +- tools/utils/CreateTemplate.hx | 42 +- tools/utils/JavaExternGenerator.hx | 4 +- tools/utils/PlatformSetup.hx | 214 +- tools/utils/publish/FirefoxMarketplace.hx | 864 ++++---- 65 files changed, 15641 insertions(+), 1501 deletions(-) create mode 100644 src/lime/tools/AIRHelper.hx create mode 100644 src/lime/tools/AndroidHelper.hx create mode 100644 src/lime/tools/ApplicationData.hx create mode 100644 src/lime/tools/Architecture.hx create mode 100644 src/lime/tools/Asset.hx create mode 100644 src/lime/tools/AssetEncoding.hx create mode 100644 src/lime/tools/AssetHelper.hx create mode 100644 src/lime/tools/AssetType.hx create mode 100644 src/lime/tools/CLICommand.hx create mode 100644 src/lime/tools/CLIHelper.hx create mode 100644 src/lime/tools/CPPHelper.hx create mode 100644 src/lime/tools/CSHelper.hx create mode 100644 src/lime/tools/Command.hx create mode 100644 src/lime/tools/CommandHelper.hx create mode 100644 src/lime/tools/ConfigData.hx create mode 100644 src/lime/tools/ConfigHelper.hx create mode 100644 src/lime/tools/Dependency.hx create mode 100644 src/lime/tools/DeploymentHelper.hx create mode 100644 src/lime/tools/ElectronHelper.hx create mode 100644 src/lime/tools/FlashHelper.hx create mode 100644 src/lime/tools/HTML5Helper.hx create mode 100644 src/lime/tools/HXProject.hx create mode 100644 src/lime/tools/IOSHelper.hx create mode 100644 src/lime/tools/Icon.hx create mode 100644 src/lime/tools/IconHelper.hx create mode 100644 src/lime/tools/ImageHelper.hx create mode 100644 src/lime/tools/JavaHelper.hx create mode 100644 src/lime/tools/Keystore.hx create mode 100644 src/lime/tools/Library.hx create mode 100644 src/lime/tools/MetaData.hx create mode 100644 src/lime/tools/ModuleData.hx create mode 100644 src/lime/tools/ModuleHelper.hx create mode 100644 src/lime/tools/NekoHelper.hx create mode 100644 src/lime/tools/NodeJSHelper.hx create mode 100644 src/lime/tools/Orientation.hx create mode 100644 src/lime/tools/Platform.hx create mode 100644 src/lime/tools/PlatformTarget.hx create mode 100644 src/lime/tools/PlatformTargetMain.hx create mode 100644 src/lime/tools/PlatformType.hx create mode 100644 src/lime/tools/Project.hx create mode 100644 src/lime/tools/ProjectHelper.hx create mode 100644 src/lime/tools/ProjectXMLParser.hx create mode 100644 src/lime/tools/SplashScreen.hx create mode 100644 src/lime/tools/TVOSHelper.hx create mode 100644 src/lime/tools/TizenHelper.hx create mode 100644 src/lime/tools/WindowData.hx create mode 100644 src/lime/tools/XCodeHelper.hx diff --git a/src/lime/tools/AIRHelper.hx b/src/lime/tools/AIRHelper.hx new file mode 100644 index 000000000..f56fb3b12 --- /dev/null +++ b/src/lime/tools/AIRHelper.hx @@ -0,0 +1,361 @@ +package lime.tools; + + +import haxe.io.Path; +import hxp.*; +import sys.FileSystem; + + +class AIRHelper { + + + public static function build (project:Project, workingDirectory:String, targetPlatform:Platform, targetPath:String, applicationXML:String, files:Array, fileDirectory:String = null):String { + + //var airTarget = "air"; + //var extension = ".air"; + var airTarget = "bundle"; + var extension = ""; + + switch (targetPlatform) { + + case MAC: + + // extension = ".app"; + + case IOS: + + if (project.targetFlags.exists ("simulator")) { + + if (project.debug) { + + airTarget = "ipa-debug-interpreter-simulator"; + + } else { + + airTarget = "ipa-test-interpreter-simulator"; + + } + + } else { + + if (project.debug) { + + airTarget = "ipa-debug"; + + } else { + + airTarget = "ipa-test"; + + } + + } + + // extension = ".ipa"; + + case ANDROID: + + if (project.debug) { + + airTarget = "apk-debug"; + + } else { + + airTarget = "apk"; + + } + + // extension = ".apk"; + + default: + + } + + var signingOptions = []; + + if (project.keystore != null) { + + var keystore = PathHelper.tryFullPath (project.keystore.path); + var keystoreType = project.keystore.type != null ? project.keystore.type : "pkcs12"; + + signingOptions.push ("-storetype"); + signingOptions.push (keystoreType); + signingOptions.push ("-keystore"); + signingOptions.push (keystore); + + if (project.keystore.alias != null) { + + signingOptions.push ("-alias"); + signingOptions.push (project.keystore.alias); + + } + + if (project.keystore.password != null) { + + signingOptions.push ("-storepass"); + signingOptions.push (project.keystore.password); + + } + + if (project.keystore.aliasPassword != null) { + + signingOptions.push ("-keypass"); + signingOptions.push (project.keystore.aliasPassword); + + } + + } else { + + signingOptions.push ("-storetype"); + signingOptions.push ("pkcs12"); + signingOptions.push ("-keystore"); + signingOptions.push (PathHelper.findTemplate (project.templatePaths, "air/debug.pfx")); + signingOptions.push ("-storepass"); + signingOptions.push ("samplePassword"); + + } + + var args = [ "-package" ]; + + // TODO: Is this an old workaround fixed in newer AIR SDK? + + if (airTarget == "air" || airTarget == "bundle") { + + args = args.concat (signingOptions); + args.push ("-target"); + args.push (airTarget); + + } else { + + args.push ("-target"); + args.push (airTarget); + + if (project.debug) { + + args.push ("-connect"); + + if (project.config.exists ("air.connect")) { + + args.push(project.config.getString ("air.connect")); + + } + + } + + args = args.concat (signingOptions); + + } + + if (targetPlatform == IOS) { + + var provisioningProfile = IOSHelper.getProvisioningFile (project); + + if (provisioningProfile != "") { + + args.push ("-provisioning-profile"); + args.push (provisioningProfile); + + } + + } + + args = args.concat ([ targetPath + extension, applicationXML ]); + + if (targetPlatform == IOS && PlatformHelper.hostPlatform == MAC && project.targetFlags.exists ("simulator")) { + + args.push ("-platformsdk"); + args.push (IOSHelper.getSDKDirectory (project)); + + } + + if (fileDirectory != null && fileDirectory != "") { + + args.push ("-C"); + args.push (fileDirectory); + + } + + args = args.concat (files); + + var extDirs:Array = getExtDirs(project); + + if (extDirs.length > 0) { + + args.push("-extdir"); + + for (extDir in extDirs) { + + args.push(extDir); + + } + } + + if (targetPlatform == ANDROID) { + + Sys.putEnv ("AIR_NOANDROIDFLAIR", "true"); + + } + + if (targetPlatform == IOS) { + + Sys.putEnv ("AIR_IOS_SIMULATOR_DEVICE", XCodeHelper.getSimulatorName (project)); + + } + + ProcessHelper.runCommand (workingDirectory, project.defines.get ("AIR_SDK") + "/bin/adt", args); + + return targetPath + extension; + + } + + + public static function getExtDirs(project:Project):Array { + + var extDirs:Array = []; + + for (dependency in project.dependencies) { + + var extDir:String = FileSystem.fullPath(Path.directory(dependency.path)); + + if (StringTools.endsWith (dependency.path, ".ane") && extDirs.indexOf(extDir) == -1) { + + extDirs.push(extDir); + + } + + } + + return extDirs; + + } + + + public static function run (project:Project, workingDirectory:String, targetPlatform:Platform, applicationXML:String, rootDirectory:String = null):Void { + + if (targetPlatform == ANDROID) { + + AndroidHelper.initialize (project); + AndroidHelper.install (project, FileSystem.fullPath (workingDirectory) + "/" + (rootDirectory != null ? rootDirectory + "/" : "") + project.app.file + ".apk"); + AndroidHelper.run (project.meta.packageName + "/.AppEntry"); + + } else if (targetPlatform == IOS) { + + var args = [ "-platform", "ios" ]; + + if (project.targetFlags.exists ("simulator")) { + + args.push ("-device"); + args.push ("ios-simulator"); + args.push ("-platformsdk"); + args.push (IOSHelper.getSDKDirectory (project)); + + ProcessHelper.runCommand ("", "killall", [ "iPhone Simulator" ], true, true); + + } + + ProcessHelper.runCommand (workingDirectory, project.defines.get ("AIR_SDK") + "/bin/adt", [ "-uninstallApp" ].concat (args).concat ([ "-appid", project.meta.packageName ]), true, true); + ProcessHelper.runCommand (workingDirectory, project.defines.get ("AIR_SDK") + "/bin/adt", [ "-installApp" ].concat (args).concat ([ "-package", FileSystem.fullPath (workingDirectory) + "/" + (rootDirectory != null ? rootDirectory + "/" : "") + project.app.file + ".ipa" ])); + ProcessHelper.runCommand (workingDirectory, project.defines.get ("AIR_SDK") + "/bin/adt", [ "-launchApp" ].concat (args).concat ([ "-appid", project.meta.packageName ]), true, true); + + if (project.targetFlags.exists ("simulator")) { + + var simulatorAppPath:String = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app/"; + + if (!FileSystem.exists(simulatorAppPath)) { + + simulatorAppPath = "/Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/"; + + } + + ProcessHelper.runCommand ("", "open", [ simulatorAppPath ]); + + } + + } else { + + var extDirs:Array = getExtDirs(project); + + var profile:String = extDirs.length > 0 ? "extendedDesktop" : "desktop"; + + var args = [ "-profile", profile ]; + + if (!project.debug) { + + args.push ("-nodebug"); + + } + + if (extDirs.length > 0) { + + args.push("-extdir"); + + for (extDir in extDirs) { + + if (!FileSystem.exists(extDir + "/adl")) { + + Log.error("Create " + extDir + "/adl directory, and extract your ANE files to .ane directories."); + + } + + args.push(extDir + "/adl"); + + } + } + + args.push (applicationXML); + + if (rootDirectory != null && rootDirectory != "") { + + args.push (rootDirectory); + + } + + ProcessHelper.runCommand (workingDirectory, project.defines.get ("AIR_SDK") + "/bin/adl", args); + + } + + } + + + public static function trace (project:Project, workingDirectory:String, targetPlatform:Platform, applicationXML:String, rootDirectory:String = null) { + + if (targetPlatform == ANDROID) { + + AndroidHelper.initialize (project); + var deviceID = null; + var adbFilter = null; + + // if (!Log.verbose) { + + if (project.debug) { + + adbFilter = project.meta.packageName + ":I ActivityManager:I *:S"; + + } else { + + adbFilter = project.meta.packageName + ":I *:S"; + + } + + // } + + AndroidHelper.trace (project, project.debug, deviceID, adbFilter); + + } + + } + + + public static function uninstall (project:Project, workingDirectory:String, targetPlatform:Platform, applicationXML:String, rootDirectory:String = null) { + + if (targetPlatform == ANDROID) { + + AndroidHelper.initialize (project); + var deviceID = null; + AndroidHelper.uninstall (project.meta.packageName, deviceID); + + } + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/AndroidHelper.hx b/src/lime/tools/AndroidHelper.hx new file mode 100644 index 000000000..9cff536a7 --- /dev/null +++ b/src/lime/tools/AndroidHelper.hx @@ -0,0 +1,479 @@ +package lime.tools; + + +import hxp.*; +import sys.io.File; +import sys.FileSystem; + + +class AndroidHelper { + + + private static var adbName:String; + private static var adbPath:String; + private static var androidName:String; + private static var androidPath:String; + private static var emulatorName:String; + private static var emulatorPath:String; + + + public static function build (project:Project, projectDirectory:String):Void { + + if (project.environment.exists ("ANDROID_SDK")) { + + Sys.putEnv ("ANDROID_SDK", project.environment.get ("ANDROID_SDK")); + + } + + var task = "assembleDebug"; + + if (project.keystore != null) { + + task = "assembleRelease"; + + } + + if (project.environment.exists ("ANDROID_GRADLE_TASK")) { + + task = project.environment.get ("ANDROID_GRADLE_TASK"); + + } + + var args = task.split (" "); + // args.push ("--stacktrace"); + // args.push ("--debug"); + + if (Log.verbose) { + + args.push ("--info"); + + } + + if (PlatformHelper.hostPlatform != WINDOWS) { + + ProcessHelper.runCommand ("", "chmod", [ "755", PathHelper.combine (projectDirectory, "gradlew") ]); + ProcessHelper.runCommand (projectDirectory, "./gradlew", args); + + } else { + + ProcessHelper.runCommand (projectDirectory, "gradlew", args); + + } + } + + + private static function connect (deviceID:String):Void { + + if (deviceID != null && deviceID != "" && deviceID.indexOf ("emulator") == -1) { + + if (deviceID.indexOf (":") > 0) { + + deviceID = deviceID.substr (0, deviceID.indexOf (":")); + + } + + ProcessHelper.runCommand (adbPath, adbName, [ "connect", deviceID ]); + + } + + } + + + public static function getBuildToolsVersion (project:Project):String { + + var buildToolsPath = PathHelper.combine (project.environment.get ("ANDROID_SDK"), "build-tools/"); + + var version = ~/^(\d+)\.(\d+)\.(\d+)$/i; + var current = { major : 0, minor : 0, micro : 0 }; + + if (!FileSystem.exists (buildToolsPath)) { + + Log.error ("Cannot find directory \"" + buildToolsPath + "\""); + + } + + for (buildTool in FileSystem.readDirectory (buildToolsPath)) { + + //gradle only likes simple version numbers (x.y.z) + + if (!version.match (buildTool)) { + + continue; + + } + + var newVersion = { + + major: Std.parseInt (version.matched (1)), + minor: Std.parseInt (version.matched (2)), + micro: Std.parseInt (version.matched (3)) + + }; + + if (newVersion.major != current.major) { + + if (newVersion.major > current.major) { + + current = newVersion; + + } + + } else if (newVersion.minor != current.minor) { + + if (newVersion.minor > current.minor) { + + current = newVersion; + + } + + } else { + + if (newVersion.micro > current.micro) { + + current = newVersion; + + } + + } + + } + + return '${current.major}.${current.minor}.${current.micro}'; + + } + + + public static function getDeviceSDKVersion (deviceID:String):Int { + + var devices = listDevices (); + + if (devices.length > 0) { + + var tempFile = PathHelper.getTemporaryFile (); + + var args = [ "wait-for-device", "shell", "getprop", "ro.build.version.sdk", ">", tempFile ]; + + if (deviceID != null && deviceID != "") { + + args.unshift (deviceID); + args.unshift ("-s"); + + //connect (deviceID); + + } + + if (PlatformHelper.hostPlatform == MAC) { + + ProcessHelper.runCommand (adbPath, "perl", [ "-e", 'alarm shift @ARGV; exec @ARGV', "3", adbName ].concat (args), true, true); + + } else { + + ProcessHelper.runCommand (adbPath, adbName, args, true, true); + + } + + if (FileSystem.exists (tempFile)) { + + var output = File.getContent (tempFile); + FileSystem.deleteFile (tempFile); + return Std.parseInt (output); + + } + + } + + return 0; + } + + + public static function initialize (project:Project):Void { + + adbPath = project.environment.get ("ANDROID_SDK") + "/tools/"; + androidPath = project.environment.get ("ANDROID_SDK") + "/tools/"; + emulatorPath = project.environment.get ("ANDROID_SDK") + "/tools/"; + + adbName = "adb"; + androidName = "android"; + emulatorName = "emulator"; + + if (PlatformHelper.hostPlatform == WINDOWS) { + + adbName += ".exe"; + androidName += ".bat"; + emulatorName += ".exe"; + + } + + if (!FileSystem.exists (adbPath + adbName)) { + + adbPath = project.environment.get ("ANDROID_SDK") + "/platform-tools/"; + + } + + if (PlatformHelper.hostPlatform != WINDOWS) { + + adbName = "./" + adbName; + androidName = "./" + androidName; + emulatorName = "./" + emulatorName; + + } + + if (project.environment.exists ("JAVA_HOME")) { + + Sys.putEnv ("JAVA_HOME", project.environment.get ("JAVA_HOME")); + + } + + } + + + public static function install (project:Project, targetPath:String, deviceID:String = null):String { + + if (project.targetFlags.exists ("emulator") || project.targetFlags.exists ("simulator")) { + + Log.info ("", "Searching for Android emulator"); + + var devices = listDevices (); + + for (device in devices) { + + if (device.indexOf ("emulator") > -1) { + + deviceID = device; + + } + + } + + //TODO: Check emulator capabilities, if it is GPU enabled and if API LEVEL >15 (http://developer.android.com/tools/devices/emulator.html) + + if (deviceID == null) { + + var avds = listAVDs (); + + if (avds.length == 0) { + + Log.error ("Cannot find emulator, please use AVD manager to create one"); + + } + + Log.info ("Starting AVD: " + avds[0]); + + ProcessHelper.runProcess (emulatorPath, emulatorName, [ "-avd", avds[0], "-gpu", "on" ], false); + + while (deviceID == null) { + + devices = listDevices (); + + for (device in devices) { + + if (device.indexOf ("emulator") > -1) { + + deviceID = device; + + } + + } + + if (deviceID == null) { + + Sys.sleep (3); + + if (!Log.verbose) { + + Sys.print ("."); + + } + + } else { + + Sys.println (""); + + } + + } + + } + + ProcessHelper.runCommand (adbPath, adbName, [ "-s", deviceID, "shell", "input", "keyevent", "82" ]); + + } + + var args = [ "install", "-r" ]; + + //if (getDeviceSDKVersion (deviceID) > 16) { + + args.push ("-d"); + + //} + + args.push (targetPath); + + if (deviceID != null && deviceID != "") { + + args.unshift (deviceID); + args.unshift ("-s"); + + connect (deviceID); + + } + + ProcessHelper.runCommand (adbPath, adbName, args); + + return deviceID; + + } + + + public static function listAVDs ():Array { + + var avds = new Array (); + var output = ProcessHelper.runProcess (androidPath, androidName, [ "list", "avd" ]); + + if (output != null && output != "") { + + for (line in output.split ("\n")) { + + if (line.indexOf ("Name") > -1) { + + avds.push (StringTools.trim (line.substr (line.indexOf ("Name") + 6))); + + } + + } + + } + + return avds; + + } + + + public static function listDevices ():Array { + + var devices = new Array (); + var output = ""; + + if (PlatformHelper.hostPlatform != WINDOWS) { + + var tempFile = PathHelper.getTemporaryFile (); + + ProcessHelper.runCommand (adbPath, adbName, [ "devices", ">", tempFile ], true, true); + + if (FileSystem.exists (tempFile)) { + + output = File.getContent (tempFile); + FileSystem.deleteFile (tempFile); + + } + + } else { + + output = ProcessHelper.runProcess (adbPath, adbName, [ "devices" ], true, true); + + } + + if (output != null && output != "") { + + for (line in output.split ("\n")) { + + if (line.indexOf ("device") > -1 && line.indexOf ("attached") == -1) { + + devices.push (StringTools.trim (line.substr (0, line.indexOf ("device")))); + + } + + } + + } + + return devices; + + } + + + public static function run (activityName:String, deviceID:String = null):Void { + + var args = [ "shell", "am", "start", "-a", "android.intent.action.MAIN", "-n", activityName ]; + + if (deviceID != null && deviceID != "") { + + args.unshift (deviceID); + args.unshift ("-s"); + + connect (deviceID); + + } + + ProcessHelper.runCommand (adbPath, adbName, args); + + } + + + public static function trace (project:Project, debug:Bool, deviceID:String = null, customFilter:String = null):Void { + + // Use -DFULL_LOGCAT or if you do not want to filter log messages + + var args = [ "logcat" ]; + + if (deviceID != null && deviceID != "") { + + args.unshift (deviceID); + args.unshift ("-s"); + + connect (deviceID); + + } + + if (customFilter != null) { + + ProcessHelper.runCommand (adbPath, adbName, args.concat ([ customFilter ])); + + } else if (project.environment.exists("FULL_LOGCAT") || Log.verbose) { + + ProcessHelper.runCommand (adbPath, adbName, args.concat ([ "-c" ])); + ProcessHelper.runCommand (adbPath, adbName, args); + + } else if (debug) { + + var filter = "*:E"; + var includeTags = [ "lime", "Lime", "Main", "GameActivity", "SDLActivity", "GLThread", "trace", "Haxe" ]; + + for (tag in includeTags) { + + filter += " " + tag + ":D"; + + } + + Sys.println (filter); + + ProcessHelper.runCommand (adbPath, adbName, args.concat ([ filter ])); + + } else { + + ProcessHelper.runCommand (adbPath, adbName, args.concat ([ "*:S trace:I" ])); + + } + + } + + + public static function uninstall (packageName:String, deviceID:String = null):Void { + + var args = [ "uninstall", packageName ]; + + if (deviceID != null && deviceID != "") { + + args.unshift (deviceID); + args.unshift ("-s"); + + connect (deviceID); + + } + + ProcessHelper.runCommand (adbPath, adbName, args); + + } + + +} diff --git a/src/lime/tools/ApplicationData.hx b/src/lime/tools/ApplicationData.hx new file mode 100644 index 000000000..b3262d64c --- /dev/null +++ b/src/lime/tools/ApplicationData.hx @@ -0,0 +1,14 @@ +package lime.tools; + + +typedef ApplicationData = { + + @:optional var file:String; + @:optional var init:String; + @:optional var main:String; + @:optional var path:String; + @:optional var preloader:String; + @:optional var swfVersion:Float; + @:optional var url:String; + +} \ No newline at end of file diff --git a/src/lime/tools/Architecture.hx b/src/lime/tools/Architecture.hx new file mode 100644 index 000000000..a35423772 --- /dev/null +++ b/src/lime/tools/Architecture.hx @@ -0,0 +1,16 @@ +package lime.tools; + + +enum Architecture { + + ARMV5; + ARMV6; + ARMV7; + ARMV7S; + ARM64; + X86; + X64; + MIPS; + MIPSEL; + +} \ No newline at end of file diff --git a/src/lime/tools/Asset.hx b/src/lime/tools/Asset.hx new file mode 100644 index 000000000..56f44db8d --- /dev/null +++ b/src/lime/tools/Asset.hx @@ -0,0 +1,146 @@ +package lime.tools; + + +import haxe.io.Path; +import hxp.FileHelper; +import hxp.ObjectHelper; +import hxp.StringHelper; +import hxp.PathHelper; +import lime.tools.AssetType; +import sys.FileSystem; + +@:access(lime.tools.AssetHelper) + + +class Asset { + + + public var data:Dynamic; + public var embed:Null; + public var encoding:AssetEncoding; + public var flatName:String; + public var format:String; + public var glyphs:String; + public var id:String; + public var library:String; + //public var path:String; + //public var rename:String; + public var resourceName:String; + public var sourcePath:String; + public var targetPath:String; + public var type:AssetType; + + + public function new (path:String = "", rename:String = "", type:AssetType = null, embed:Null = null, setDefaults:Bool = true) { + + if (!setDefaults) return; + + this.embed = embed; + sourcePath = PathHelper.standardize (path); + + if (rename == "") { + + targetPath = path; + + } else { + + targetPath = rename; + + } + + id = targetPath; + resourceName = targetPath; + flatName = StringHelper.getFlatName (targetPath); + format = Path.extension (path).toLowerCase (); + glyphs = "32-255"; + + if (type == null) { + + var extension = Path.extension (path); + if (extension != null) extension = extension.toLowerCase (); + + if (AssetHelper.knownExtensions.exists (extension)) { + + this.type = AssetHelper.knownExtensions.get (extension); + + } else { + + switch (extension) { + + case "bundle": + + this.type = AssetType.MANIFEST; + + case "ogg", "m4a": + + if (FileSystem.exists (path)) { + + var stat = FileSystem.stat (path); + + //if (stat.size > 1024 * 128) { + if (stat.size > 1024 * 1024) { + + this.type = AssetType.MUSIC; + + } else { + + this.type = AssetType.SOUND; + + } + + } else { + + this.type = AssetType.SOUND; + + } + + default: + + if (path != "" && FileHelper.isText (path)) { + + this.type = AssetType.TEXT; + + } else { + + this.type = AssetType.BINARY; + + } + + } + + } + + } else { + + this.type = type; + + } + + } + + + public function clone ():Asset { + + var asset = new Asset ("", "", null, null, false); + + asset.data = data; + asset.embed = embed; + asset.encoding = encoding; + asset.flatName = flatName; + asset.format = format; + asset.glyphs = glyphs; + asset.id = id; + asset.library = library; + asset.resourceName = resourceName; + asset.sourcePath = sourcePath; + asset.targetPath = targetPath; + asset.type = type; + + //ObjectHelper.copyFields (this, asset); + + return asset; + + } + + +} diff --git a/src/lime/tools/AssetEncoding.hx b/src/lime/tools/AssetEncoding.hx new file mode 100644 index 000000000..be558f21a --- /dev/null +++ b/src/lime/tools/AssetEncoding.hx @@ -0,0 +1,9 @@ +package lime.tools; + + +enum AssetEncoding { + + NONE; + BASE64; + +} \ No newline at end of file diff --git a/src/lime/tools/AssetHelper.hx b/src/lime/tools/AssetHelper.hx new file mode 100644 index 000000000..92c18bfbd --- /dev/null +++ b/src/lime/tools/AssetHelper.hx @@ -0,0 +1,832 @@ +package lime.tools; #if lime + + +import haxe.io.Path; +import haxe.Serializer; +import haxe.Unserializer; +import hxp.PathHelper; +import hxp.*; +import lime.tools.AssetType; +import lime.tools.Asset; +import lime.tools.Project; +import lime.tools.Library; +import lime.utils.AssetManifest; +import lime.utils.Bytes; +import sys.io.File; +import sys.io.FileOutput; +import sys.FileSystem; + + +class AssetHelper { + + + private static var DEFAULT_LIBRARY_NAME = "default"; + private static var knownExtensions:Map; + + + private static function __init__ ():Void { + + knownExtensions = [ + + "jpg" => IMAGE, + "jpeg" => IMAGE, + "png" => IMAGE, + "gif" => IMAGE, + "webp" => IMAGE, + "bmp" => IMAGE, + "tiff" => IMAGE, + "jfif" => IMAGE, + "otf" => FONT, + "ttf" => FONT, + "wav" => SOUND, + "wave" => SOUND, + "mp3" => MUSIC, + "mp2" => MUSIC, + "exe" => BINARY, + "bin" => BINARY, + "so" => BINARY, + "pch" => BINARY, + "dll" => BINARY, + "zip" => BINARY, + "tar" => BINARY, + "gz" => BINARY, + "fla" => BINARY, + "swf" => BINARY, + "atf" => BINARY, + "psd" => BINARY, + "awd" => BINARY, + "txt" => TEXT, + "text" => TEXT, + "xml" => TEXT, + "java" => TEXT, + "hx" => TEXT, + "cpp" => TEXT, + "c" => TEXT, + "h" => TEXT, + "cs" => TEXT, + "js" => TEXT, + "mm" => TEXT, + "hxml" => TEXT, + "html" => TEXT, + "json" => TEXT, + "css" => TEXT, + "gpe" => TEXT, + "pbxproj" => TEXT, + "plist" => TEXT, + "properties" => TEXT, + "ini" => TEXT, + "hxproj" => TEXT, + "nmml" => TEXT, + "lime" => TEXT, + "svg" => TEXT, + + ]; + + } + + + public static function copyAsset (asset:Asset, destination:String, context:Dynamic = null) { + + if (asset.sourcePath != "") { + + FileHelper.copyFile (asset.sourcePath, destination, context, asset.type == TEMPLATE); + + } else { + + try { + + if (asset.encoding == AssetEncoding.BASE64) { + + File.saveBytes (destination, StringHelper.base64Decode (asset.data)); + + } else if (Std.is (asset.data, Bytes)) { + + File.saveBytes (destination, cast asset.data); + + } else { + + File.saveContent (destination, Std.string (asset.data)); + + } + + } catch (e:Dynamic) { + + Log.error ("Cannot write to file \"" + destination + "\""); + + } + + } + + } + + + public static function copyAssetIfNewer (asset:Asset, destination:String) { + + if (asset.sourcePath != "") { + + if (FileHelper.isNewer (asset.sourcePath, destination)) { + + FileHelper.copyFile (asset.sourcePath, destination, null, asset.type == TEMPLATE); + + } + + } else { + + PathHelper.mkdir (Path.directory (destination)); + + Log.info ("", " - \x1b[1mWriting file:\x1b[0m " + destination); + + try { + + if (asset.encoding == AssetEncoding.BASE64) { + + File.saveBytes (destination, StringHelper.base64Decode (asset.data)); + + } else if (Std.is (asset.data, Bytes)) { + + File.saveBytes (destination, cast asset.data); + + } else { + + File.saveContent (destination, Std.string (asset.data)); + + } + + } catch (e:Dynamic) { + + Log.error ("Cannot write to file \"" + destination + "\""); + + } + + } + + } + + + public static function createManifest (project:Project, library:String = null, targetPath:String = null):AssetManifest { + + var manifest = new AssetManifest (); + var pathGroups = new Map> (); + + var libraries = new Map (); + if (library == null) library = DEFAULT_LIBRARY_NAME; + + for (lib in project.libraries) { + + libraries[lib.name] = lib; + + } + + var assetData; + + for (asset in project.assets) { + + assetData = getAssetData (project, pathGroups, libraries, library, asset); + + if (assetData != null) { + + manifest.assets.push (assetData); + + } + + } + + if (targetPath != null) { + + PathHelper.mkdir (Path.directory (targetPath)); + Log.info ("", " - \x1b[1mWriting asset manifest:\x1b[0m " + targetPath); + File.saveContent (targetPath, manifest.serialize ()); + + } + + return manifest; + + } + + + public static function createManifests (project:Project, targetDirectory:String = null):Array { + + var libraryNames = new Map (); + var hasManifest = new Map (); + + for (asset in project.assets) { + + if (asset.library != null && !libraryNames.exists (asset.library)) { + + libraryNames[asset.library] = true; + + } + + if (asset.type == MANIFEST) { + + hasManifest.set (asset.library != null ? asset.library : DEFAULT_LIBRARY_NAME, true); + + } + + } + + var manifest = null; + var manifests = []; + + if (!hasManifest.exists (DEFAULT_LIBRARY_NAME)) { + + manifest = createManifest (project); + manifest.name = DEFAULT_LIBRARY_NAME; + manifests.push (manifest); + + } + + for (library in libraryNames.keys ()) { + + if (!hasManifest.exists (library)) { + + manifest = createManifest (project, library); + manifest.name = library; + manifests.push (manifest); + + } + + } + + if (targetDirectory != null) { + + PathHelper.mkdir (targetDirectory); + var targetPath; + + for (manifest in manifests) { + + targetPath = PathHelper.combine (targetDirectory, manifest.name + ".json"); + Log.info ("", " - \x1b[1mWriting asset manifest:\x1b[0m " + targetPath); + File.saveContent (targetPath, manifest.serialize ()); + + } + + } + + return manifests; + + } + + + private static function getAssetData (project:Project, pathGroups:Map>, libraries:Map, library:String, asset:Asset):Dynamic { + + if ((asset.library != null && asset.library != library) || asset.type == TEMPLATE) return null; + if (asset.library == null && library != DEFAULT_LIBRARY_NAME) return null; + + var size = 100; + + if (FileSystem.exists (asset.sourcePath)) { + + size = FileSystem.stat (asset.sourcePath).size; + + } + + var assetData:Dynamic = { + + id: asset.id, + size: size, + type: Std.string (asset.type) + + }; + + if (project.target == FLASH || project.target == AIR) { + + if (asset.embed != false || asset.type == FONT) { + + assetData.className = "__ASSET__" + asset.flatName; + + } else { + + assetData.path = asset.resourceName; + + } + + if (asset.embed == false && asset.library != null && libraries.exists (asset.library)) { + + assetData.preload = libraries[asset.library].preload; + + } + + } else if (project.target == HTML5) { + + if (asset.type == FONT) { + + assetData.className = "__ASSET__" + asset.flatName; + assetData.preload = true; + + } else { + + assetData.path = asset.resourceName; + + if (asset.embed != false || (asset.library != null && libraries.exists (asset.library) && libraries[asset.library].preload)) { + + assetData.preload = true; + + } + + if (asset.type == MUSIC || asset.type == SOUND) { + + var soundName = Path.withoutExtension (assetData.path); + + if (!pathGroups.exists (soundName)) { + + pathGroups.set (soundName, [ assetData.path ]); + + } else { + + pathGroups[soundName].push (assetData.path); + Reflect.deleteField (assetData, "preload"); + + } + + Reflect.deleteField (assetData, "path"); + assetData.pathGroup = pathGroups[soundName]; + + } + + } + + } else { + + if (project.target == EMSCRIPTEN && (asset.embed != false || (asset.library != null && libraries.exists (asset.library) && libraries[asset.library].preload))) { + + assetData.preload = true; + + } + + if (asset.embed == true || asset.type == FONT) { + + assetData.className = "__ASSET__" + asset.flatName; + + } else { + + assetData.path = asset.resourceName; + + } + + } + + return assetData; + + } + + + private static function getPackedAssetData (project:Project, output:FileOutput, pathGroups:Map>, libraries:Map, library:Library, asset:Asset):Dynamic { + + if (project.target == HTML5 && (asset.type == MUSIC || asset.type == SOUND || asset.type == FONT)) { + + return getAssetData (project, pathGroups, libraries, library.name, asset); + + } + + if (asset.type == TEMPLATE) return null; + if (asset.library == library.name || (asset.library == null && library.name == DEFAULT_LIBRARY_NAME)) { + + var assetData:Dynamic = { + + id: asset.id, + size: 0, + type: Std.string (asset.type), + position: output.tell () + + }; + + if (project.target == HTML5 && asset.type == FONT) { + + assetData.className = "__ASSET__" + asset.flatName; + assetData.preload = true; + + } else { + + switch (library.type) { + + case "deflate", "zip": + + if (asset.data != null) { + + var bytes:Bytes = asset.data; + bytes = bytes.compress (DEFLATE); + output.writeBytes (bytes, 0, bytes.length); + + } else if (asset.sourcePath != null) { + + var tempBytes:Bytes = File.getBytes (asset.sourcePath); + tempBytes = tempBytes.compress (DEFLATE); + output.writeBytes (tempBytes, 0, tempBytes.length); + + } + + case "gzip": + + if (asset.data != null) { + + var bytes:Bytes = asset.data; + bytes = bytes.compress (GZIP); + output.writeBytes (bytes, 0, asset.data.length); + + } else if (asset.sourcePath != null) { + + var tempBytes:Bytes = File.getBytes (asset.sourcePath); + tempBytes = tempBytes.compress (GZIP); + output.writeBytes (tempBytes, 0, tempBytes.length); + + } + + default: + + if (asset.data != null) { + + output.writeBytes (asset.data, 0, asset.data.length); + + } else if (asset.sourcePath != null) { + + var input = File.read (asset.sourcePath, true); + output.writeInput (input); + input.close (); + + } + + } + + } + + if (project.target == HTML5 && asset.type == IMAGE) { + + assetData.preload = true; + + } + + var position = output.tell (); + assetData.length = position - assetData.position; + + asset.library = library.name; + + // asset.sourcePath = ""; + + if (project.target != HTML5 || asset.type != FONT) { + + asset.targetPath = null; + + } + + asset.data = null; + + return assetData; + + } else { + + return null; + + } + + } + + + private static function isPackedLibrary (project:Project, library:Library) { + + if (project.target == FLASH && library.embed != false) return false; + + return switch (library.type) { + + case "pak", "pack", "gzip", "zip", "deflate": true; + default: false; + + } + + } + + + public static function processLibraries (project:Project, targetDirectory:String = null):Void { + + var hasManifest = new Map (); + var libraryMap = new Map (); + + for (library in project.libraries) { + + libraryMap[library.name] = true; + + } + + var library; + + for (asset in project.assets) { + + if (asset.library != null && asset.library != DEFAULT_LIBRARY_NAME && !libraryMap.exists (asset.library)) { + + library = new Library (null, asset.library); + project.libraries.push (library); + + libraryMap[asset.library] = true; + + } + + if (asset.type == MANIFEST) { + + hasManifest.set (asset.library != null ? asset.library : DEFAULT_LIBRARY_NAME, true); + + } + + } + + if (!libraryMap.exists (DEFAULT_LIBRARY_NAME)) { + + library = new Library (null, DEFAULT_LIBRARY_NAME); + project.libraries.push (library); + + } + + var handlers = new Array (); + var hasPackedLibraries = false; + var type; + + for (library in project.libraries) { + + type = library.type; + + if (library.sourcePath != null || type != null) { + + if (type == null) { + + type = Path.extension (library.sourcePath).toLowerCase (); + + } + + if (project.libraryHandlers.exists (type)) { + + var handler = project.libraryHandlers.get (type); + + handlers.remove (handler); + handlers.push (handler); + + library.type = type; + + } else if (isPackedLibrary (project, library)) { + + hasPackedLibraries = true; + + } + + } + + } + + if (handlers.length > 0) { + + var projectData = Serializer.run (project); + var temporaryFile = PathHelper.getTemporaryFile (); + + File.saveContent (temporaryFile, projectData); + + for (handler in handlers) { + + var outputFile = PathHelper.getTemporaryFile (); + var args = [ "run", handler, "process", temporaryFile, outputFile ]; + + if (Log.verbose) { + + args.push ("-verbose"); + + } + + if (targetDirectory != null) { + + args.push ("--targetDirectory=" + PathHelper.tryFullPath (targetDirectory)); + + } + + try { + + HaxelibHelper.runCommand ("", args, false); + + } catch (e:Dynamic) { + + var types = []; + + for (library in project.libraries) { + + if (library.type != null && project.libraryHandlers.exists (library.type) && project.libraryHandlers.get (library.type) == handler) { + + types.push (library.type); + + } + + } + + Log.error ("Could not process asset libraries (" + types.join (", ") + ")"); + + } + + if (FileSystem.exists (outputFile)) { + + try { + + var output = File.getContent (outputFile); + var data:Project = Unserializer.run (output); + project.merge (data); + + } catch (e:Dynamic) { + + Log.error (e); + + } + + try { + + FileSystem.deleteFile (outputFile); + + } catch (e:Dynamic) {} + + } + + } + + try { + + FileSystem.deleteFile (temporaryFile); + + } catch (e:Dynamic) {} + + } + + if (hasPackedLibraries) { + + processPackedLibraries (project, targetDirectory); + + } + + var manifest, asset; + + for (library in project.libraries) { + + if (library.type == null || (project.target == FLASH && library.embed != false && ["pak", "pack", "gzip", "zip", "deflate"].indexOf (library.type) > -1)) { + + if (library.name == DEFAULT_LIBRARY_NAME) { + + library.preload = true; + + } + + if (!hasManifest.exists (library.name)) { + + manifest = createManifest (project, library.name != DEFAULT_LIBRARY_NAME ? library.name : null); + + asset = new Asset ("", "manifest/" + library.name + ".json", AssetType.MANIFEST); + asset.library = library.name; + asset.data = manifest.serialize (); + + if (manifest.assets.length == 0 || (project.target == HTML5 && library.name == DEFAULT_LIBRARY_NAME)) { + + asset.embed = true; + + } else { + + // TODO: Make this assumption elsewhere? + + var allEmbedded = true; + + for (childAsset in manifest.assets) { + + if (!Reflect.hasField (childAsset, "className") || childAsset.className == null) { + + allEmbedded = false; + break; + + } + + } + + if (allEmbedded) asset.embed = true; + + } + + project.assets.push (asset); + + } + + } + + } + + } + + + public static function processPackedLibraries (project:Project, targetDirectory:String = null):Void { + + var type, asset, cacheAvailable, cacheDirectory, filename; + var output, manifest, position, assetData:Dynamic, input; + var embeddedLibrary = false; + + var pathGroups = new Map> (); + var libraries = new Map (); + for (lib in project.libraries) { + + libraries[lib.name] = lib; + + } + + for (library in project.libraries) { + + type = library.type; + + if (isPackedLibrary (project, library)) { + + // TODO + #if !nodejs + + if (type == "zip") type = "deflate"; + + // TODO: Support library.embed=true by embedding all the assets instead of packing + + cacheAvailable = false; + cacheDirectory = null; + + if (targetDirectory != null) { + + manifest = new AssetManifest (); + + cacheDirectory = targetDirectory + "/obj/libraries/"; + filename = library.name + ".pak"; + + // TODO: Support caching + + PathHelper.mkdir (cacheDirectory); + + if (FileSystem.exists (cacheDirectory + filename)) { + + FileSystem.deleteFile (cacheDirectory + filename); + + } + + output = File.write (cacheDirectory + filename, true); + position = 0; + + try { + + var assetData; + + for (asset in project.assets) { + + assetData = getPackedAssetData (project, output, pathGroups, libraries, library, asset); + + if (assetData != null) { + + manifest.assets.push (assetData); + + } + + } + + } catch (e:Dynamic) { + + output.close (); + FileSystem.deleteFile (cacheDirectory + filename); + + #if neko + neko.Lib.rethrow (e); + #end + + } + + output.close (); + + var libraryAsset = new Asset (cacheDirectory + filename, "lib/" + filename, AssetType.BINARY); + libraryAsset.library = library.name; + project.assets.push (libraryAsset); + + var data = new Asset ("", "manifest/" + library.name + ".json", AssetType.MANIFEST); + data.library = library.name; + manifest.libraryType = "lime.utils.PackedAssetLibrary"; + manifest.libraryArgs = [ "lib/" + filename, library.type ]; + data.data = manifest.serialize (); + data.embed = true; + + project.assets.push (data); + embeddedLibrary = true; + + } + + if (library.name == DEFAULT_LIBRARY_NAME) { + + library.preload = true; + + } + + #end + + } + + } + + if (embeddedLibrary) { + + project.haxeflags.push ("lime.utils.PackedAssetLibrary"); + + } + + } + + +} + + +#end \ No newline at end of file diff --git a/src/lime/tools/AssetType.hx b/src/lime/tools/AssetType.hx new file mode 100644 index 000000000..4929e9fdb --- /dev/null +++ b/src/lime/tools/AssetType.hx @@ -0,0 +1,15 @@ +package lime.tools; + +enum AssetType { + + BINARY; + FONT; + IMAGE; + MANIFEST; + MOVIE_CLIP; + MUSIC; + SOUND; + TEMPLATE; + TEXT; + +} \ No newline at end of file diff --git a/src/lime/tools/CLICommand.hx b/src/lime/tools/CLICommand.hx new file mode 100644 index 000000000..4560d3668 --- /dev/null +++ b/src/lime/tools/CLICommand.hx @@ -0,0 +1,20 @@ +package lime.tools; + + +//"Command-Line Interface Command" +class CLICommand { + + + public var command:String; + public var args:Array; + + + public function new (command:String, args:Array = null) { + + this.command = command; + this.args = args != null ? args : new Array (); + + } + + +} diff --git a/src/lime/tools/CLIHelper.hx b/src/lime/tools/CLIHelper.hx new file mode 100644 index 000000000..7f7b471b9 --- /dev/null +++ b/src/lime/tools/CLIHelper.hx @@ -0,0 +1,111 @@ +package lime.tools; + + +import haxe.io.Eof; +import hxp.*; + + +class CLIHelper { + + + public static function ask (question:String, options:Array = null):Answer { + + if (options == null) { + + options = ["y", "n", "a"]; + + } + + while (true) { + + Log.print (Log.accentColor + question + "\x1b[0m \x1b[3;37m[" + options.join ("/") + "]\x1b[0m ? "); + + try { + + switch (readLine ()) { + + case "n": return NO; + case "y": return YES; + case "a": return ALWAYS; + case _ => x if (options.indexOf (x) > -1): return CUSTOM (x); + + } + + } catch (e:Dynamic) { + + Sys.exit (0); + + } + + } + + return null; + + } + + + public static inline function getChar ():Int { + + return Sys.getChar (false); + + } + + + public static function param (name:String, passwd:Bool = false):String { + + Log.print (name + ": "); + + if (passwd) { + + var s = new StringBuf (); + var c; + while ((c = getChar ()) != 13) + s.addChar (c); + + Log.print (""); + Log.println (""); + + return s.toString (); + + } + + try { + + return readLine (); + + } catch (e:Eof) { + + return ""; + + } + + } + + + public static function progress (prefix:String, now:Int, total:Int):Void { + + var percent = Math.floor ((now / total) * 100); + + Log.print ('\r$prefix $now/$total ($percent%)'); + + } + + + public static inline function readLine ():String { + + return Sys.stdin ().readLine (); + + } + + +} + + +enum Answer { + + YES; + NO; + ALWAYS; + CUSTOM (answer:String); + +} \ No newline at end of file diff --git a/src/lime/tools/CPPHelper.hx b/src/lime/tools/CPPHelper.hx new file mode 100644 index 000000000..3c786101e --- /dev/null +++ b/src/lime/tools/CPPHelper.hx @@ -0,0 +1,331 @@ +package lime.tools; + + +import hxp.Log; +import hxp.PlatformHelper; +import hxp.ProcessHelper; +import hxp.*; +import lime.tools.Project; +import lime.tools.Platform; +import sys.io.File; +import sys.FileSystem; + + +class CPPHelper { + + + private static var rebuiltLibraries = new Map (); + private static var rebuiltPaths = new Map (); + + + public static function compile (project:Project, path:String, flags:Array = null, buildFile:String = "Build.xml"):Void { + + if (project.config.getBool ("cpp.requireBuild", true)) { + + var args = [ "run", project.config.getString ("cpp.buildLibrary", "hxcpp"), buildFile ]; + var foundOptions = false; + + try { + + var options = PathHelper.combine (path, "Options.txt"); + + if (FileSystem.exists (options)) { + + args.push ("-options"); + args.push (PathHelper.tryFullPath (options)); + + // var list; + // var input = File.read (options, false); + // var text = input.readLine (); + + // if (StringTools.startsWith (text, " -D")) { + + // list = text.split (" "); + + // } else { + + // list = [ "-D" + StringTools.trim (text) ]; + + // while (!input.eof ()) { + + // list.push ("-D" + StringTools.trim (input.readLine ())); + + // } + + // list.pop (); + + // } + + // for (option in list) { + + // if (option != "" && !StringTools.startsWith (option, "-Dno_compilation") && !StringTools.startsWith (option, "-Dno-compilation")) { + + // args.push (option); + + // } + + // } + + foundOptions = true; + + } + + } catch (e:Dynamic) {} + + if (flags != null) { + + args = args.concat (flags); + + } + + if (!foundOptions) { + + for (key in project.haxedefs.keys ()) { + + var value = project.haxedefs.get (key); + + if (value == null || value == "") { + + args.push ("-D" + key); + + } else { + + args.push ("-D" + key + "=" + value); + + } + + } + + } + + if (project.debug) { + + args.push ("-debug"); + + } + + if (Log.verbose) { + + args.push ("-verbose"); + + } + + if (!Log.enableColor) { + + //args.push ("-nocolor"); + Sys.putEnv ("HXCPP_NO_COLOR", ""); + + } + + if (PlatformHelper.hostPlatform == WINDOWS && !project.environment.exists ("HXCPP_COMPILE_THREADS")) { + + var threads = 1; + + if (ProcessHelper.processorCores > 1) { + + threads = ProcessHelper.processorCores - 1; + + } + + Sys.putEnv ("HXCPP_COMPILE_THREADS", Std.string (threads)); + + } + + Sys.putEnv ("HXCPP_EXIT_ON_ERROR", ""); + + var code = HaxelibHelper.runCommand (path, args); + + if (code != 0) { + + Sys.exit (code); + + } + + } + + } + + + public static function rebuild (project:Project, commands:Array>, path:String = null, buildFile:String = null):Void { + + var buildRelease = (!project.targetFlags.exists ("debug")); + var buildDebug = (project.targetFlags.exists ("debug") || + (!project.targetFlags.exists ("rebuild") && + !project.targetFlags.exists ("release") && + !project.targetFlags.exists ("final") && + project.config.exists ("project.rebuild.fulldebug"))); + + for (haxelib in project.haxelibs) { + + if (!rebuiltLibraries.exists (haxelib.name)) { + + var defines = StringMapHelper.copy (project.defines); + defines.set ("rebuild", "1"); + + var haxelibProject = Project.fromHaxelib (haxelib, defines); + + if (haxelibProject == null) { + + haxelibProject = new Project (); + haxelibProject.config.set ("project.rebuild.path", PathHelper.combine (PathHelper.getHaxelib (haxelib), "project")); + + } + + StringMapHelper.copyKeys (project.targetFlags, haxelibProject.targetFlags); + + rebuiltLibraries.set (haxelib.name, true); + + if (!rebuiltPaths.exists (haxelibProject.config.get ("project.rebuild.path"))) { + + rebuiltPaths.set (haxelibProject.config.get ("project.rebuild.path"), true); + rebuild (haxelibProject, commands); + + } + + } + + } + + if (project.targetFlags.exists ("clean")) { + + if (buildRelease) { + + for (command in commands) { + + rebuildSingle (project, command.concat ([ "clean" ]), path, buildFile); + + } + + } + + if (buildDebug) { + + for (command in commands) { + + rebuildSingle (project, command.concat ([ "-Ddebug", "-Dfulldebug", "clean" ]), path, buildFile); + + } + + } + + + } + + for (command in commands) { + + if (buildRelease) { + + rebuildSingle (project, command, path, buildFile); + + } + + if (buildDebug) { + + rebuildSingle (project, command.concat ([ "-Ddebug", "-Dfulldebug" ]), path, buildFile); + + } + + } + + } + + + public static function rebuildSingle (project:Project, flags:Array = null, path:String = null, buildFile:String = null):Void { + + if (path == null) { + + path = project.config.get ("project.rebuild.path"); + + } + + if (path == null || !FileSystem.exists (path)) { + + return; + + } + + if (buildFile == null && project.config.exists ("project.rebuild.file")) { + + buildFile = project.config.get ("project.rebuild.file"); + + } + + if (buildFile == null) buildFile = "Build.xml"; + + if (!FileSystem.exists (PathHelper.combine (path, buildFile))) { + + return; + + } + + var args = [ "run", project.config.getString ("cpp.buildLibrary", "hxcpp"), buildFile ]; + + if (flags != null) { + + args = args.concat (flags); + + } + + for (key in project.haxedefs.keys ()) { + + var value = project.haxedefs.get (key); + + if (value == null || value == "") { + + args.push ("-D" + key); + + } else { + + args.push ("-D" + key + "=" + value); + + } + + } + + /*if (project.debug) { + + args.push ("-Ddebug"); + + }*/ + + if (project.targetFlags.exists ("static")) { + + args.push ("-Dstatic_link"); + + } + + if (Log.verbose) { + + args.push ("-verbose"); + + } + + if (!Log.enableColor) { + + //args.push ("-nocolor"); + Sys.putEnv ("HXCPP_NO_COLOR", ""); + + } + + if (PlatformHelper.hostPlatform == WINDOWS && !project.environment.exists ("HXCPP_COMPILE_THREADS")) { + + var threads = 1; + + if (ProcessHelper.processorCores > 1) { + + threads = ProcessHelper.processorCores - 1; + + } + + Sys.putEnv ("HXCPP_COMPILE_THREADS", Std.string (threads)); + + } + + Sys.putEnv ("HXCPP_EXIT_ON_ERROR", ""); + + HaxelibHelper.runCommand (path, args); + + } + + +} diff --git a/src/lime/tools/CSHelper.hx b/src/lime/tools/CSHelper.hx new file mode 100644 index 000000000..854fe19ac --- /dev/null +++ b/src/lime/tools/CSHelper.hx @@ -0,0 +1,302 @@ +package lime.tools; + +import lime.tools.Architecture; +import lime.tools.Project; +import hxp.NDLL; +import hxp.ProcessHelper; +import hxp.*; +import sys.io.File; +import sys.FileSystem; +using StringTools; + +class CSHelper { + + public static var ndllSourceFiles:Array = [ + "cs.ndll.NDLLFunction", + "cs.ndll.CFFICSLoader", + "cs.ndll.CSAbstract", + "cs.ndll.CSHandleContainer", + "cs.ndll.CSHandleScope", + "cs.ndll.CSPersistent", + "cs.ndll.DelegateConverter", + "cs.ndll.HandleUtils", + "cs.ndll.NativeMethods", + "cs.ndll.NDLLFunction", + ]; + + private static function getAndroidABIName(arch:Architecture):String { + + var name = switch(arch) { + case ARMV5: + "armeabi"; + case ARMV7: + "armeabi-v7a"; + case ARM64: + "arm64-v8a"; + case X86: + "x86"; + case X64: + "x86_64"; + case _: + null; + } + + if (name == null) { + + throw "Unsupported architecture:" + arch; + + } + + return name; + + } + + public static function getAndroidABINames (architectures:Array):String { + + var result = ""; + var first = true; + + for (arch in architectures) { + + if (first) { + + first = false; + + } else { + + result += ","; + + } + + var archName = getAndroidABIName (arch); + result += archName; + + } + + return result; + + } + + public static function getAndroidNativeLibraryPaths (libPath:String, libraries:Array, architectures:Array):Array { + + var paths = []; + + for (arch in architectures) { + + var archName = getAndroidABIName (arch); + + for (lib in libraries) { + + paths.push (FileSystem.absolutePath (libPath + "/" + archName + "/" + "lib" + lib.name + ".so").replace ("/", "\\")); + + } + + } + + return paths; + + } + + public static function copySourceFiles (templatePaths:Array, targetPath:String) { + + FileHelper.recursiveCopyTemplate (templatePaths, "cs/src", targetPath); + + } + + public static function addSourceFiles (txtPath:String, sourceFiles:Array) { + + if (sourceFiles.length == 0) { + + return; + + } + + var file = File.append (txtPath, false); + file.writeString ('\nbegin modules\n'); + + for (fileName in sourceFiles) { + + file.writeString ('M $fileName\nC $fileName\n'); + + } + + file.writeString ('end modules\n'); + file.close(); + + } + + public static function addAndroidResources (txtPath:String, resources:Array) { + + if (resources.length == 0) { + + return; + + } + + var file = File.append (txtPath, false); + file.writeString ('\nbegin android_resources\n'); + + for (resource in resources) { + + file.writeString ('$resource\n'); + + } + + file.writeString ('end android_resources\n'); + file.close(); + + } + + public static function addAssemblies (txtPath:String, assemblies:Array) { + + if (assemblies.length == 0) { + + return; + + } + + var file = File.append (txtPath, false); + file.writeString ('\nbegin libs\n'); + + for (assembly in assemblies) { + + file.writeString (assembly.replace("/", "\\") + '\n'); + + } + + file.writeString ('end libs\n'); + file.close(); + + } + + public static function addNativeLibraries (txtPath:String, libPath:String, libraries:Array, architectures:Array) { + + if (libraries.length == 0) { + + return; + + } + + var file = File.append (txtPath, false); + file.writeString ('\nbegin native_libs\n'); + + for (arch in architectures) { + + var archName = getAndroidABIName (arch); + + for (lib in libraries) { + + file.writeString (FileSystem.absolutePath(libPath + "/" + archName + "/" + "lib" + lib.name + ".so").replace("/", "\\") + '\n'); + + } + + } + + file.writeString ('end native_libs\n'); + file.close(); + + } + + public static function addAndroidABIs (txtPath:String, architectures:Array) { + + if (architectures.length == 0) { + + return; + + } + + var file = File.append (txtPath, false); + file.writeString ('\nbegin android_abis\n'); + + for (arch in architectures) { + + var archName = getAndroidABIName (arch); + file.writeString (archName + '\n'); + + } + + file.writeString ('end android_abis\n'); + file.close(); + + } + + + public static function addAssets (txtPath:String, assets:Array) { + + if (assets.length == 0) { + + return; + + } + + var file = File.append (txtPath, false); + file.writeString ('\nbegin android_assets\n'); + + for (asset in assets) { + + file.writeString (FileSystem.absolutePath(asset).replace("/", "\\") + '\n'); + + } + + file.writeString ('end android_assets\n'); + file.close(); + + } + + public static function addGUID (txtPath:String, guid:String) { + + var file = File.append (txtPath, false); + file.writeString ('\nbegin guid\n'); + + file.writeString ('$guid\n'); + + file.writeString ('end guid\n'); + file.close (); + + } + + public static function compile (project:Project, path:String, outPath:String, arch:String, platform:String, buildFile:String = "hxcs_build.txt", noCompile:Bool = false) { + + var args = [ "run", project.config.getString ("cs.buildLibrary", "hxcs"), buildFile, "--arch", arch, "--platform", platform, "--out", outPath, "--unsafe" ]; + if (noCompile) + args.push ("--no-compile"); + var code = HaxelibHelper.runCommand (path, args); + + if (code != 0) { + + Sys.exit (code); + + } + + } + + public static function buildGradleProj (path:String) { + + var gradlePath = FileSystem.absolutePath(path + "/" + "gradlew"); + ProcessHelper.runCommand (path, gradlePath, ["build", "assembleRelease"]); + + } + + inline public static function buildSln (path:String, slnPath:String, task:String = null) { + + buildCSProj (path, slnPath, task); + + } + + public static function buildCSProj (path:String, csprojPath:String, task:String = null) { + + var msBuildPath = "C:/Program Files (x86)/MSBuild/14.0/Bin/MSBuild.exe"; + var absCSProjPath = FileSystem.absolutePath(csprojPath); + var args = [absCSProjPath, "/p:Configuration=Release"]; + + if (task != null) { + + args.push ("/t:" + task); + + } + + ProcessHelper.runCommand (path, msBuildPath, args); + + } + +} diff --git a/src/lime/tools/Command.hx b/src/lime/tools/Command.hx new file mode 100644 index 000000000..7fce6d42b --- /dev/null +++ b/src/lime/tools/Command.hx @@ -0,0 +1,18 @@ +package lime.tools; + + +enum Command { + + BUILD; + CLEAN; + CONFIG; + DEPLOY; + DISPLAY; + UPDATE; + RUN; + TEST; + TRACE; + PUBLISH; + REBUILD; + +} \ No newline at end of file diff --git a/src/lime/tools/CommandHelper.hx b/src/lime/tools/CommandHelper.hx new file mode 100644 index 000000000..b1f548ee5 --- /dev/null +++ b/src/lime/tools/CommandHelper.hx @@ -0,0 +1,57 @@ +package lime.tools; + + +import lime.tools.CLICommand; +import lime.tools.Platform; +import hxp.*; + + +class CommandHelper { + + + public static function executeCommands (commands:Array):Void { + + for (c in commands) { + + Sys.command(c.command, c.args); + + } + + } + + public static function openFile (file:String):CLICommand { + + if (PlatformHelper.hostPlatform == WINDOWS) { + + return new CLICommand ("start", [ file ]); + + } else if (PlatformHelper.hostPlatform == MAC) { + + return new CLICommand ("/usr/bin/open", [ file ]); + + } else { + + return new CLICommand ("/usr/bin/xdg-open", [ file ]); + + } + + } + + + public static function interpretHaxe (mainFile:String):CLICommand { + + return new CLICommand ("haxe", [ "-main", mainFile, "--interp" ]); + + } + + + public static function fromSingleString (command:String):CLICommand { + + var args:Array = command.split (" "); + command = args.shift (); + return new CLICommand (command, args); + + } + + +} diff --git a/src/lime/tools/ConfigData.hx b/src/lime/tools/ConfigData.hx new file mode 100644 index 000000000..bcc20dae7 --- /dev/null +++ b/src/lime/tools/ConfigData.hx @@ -0,0 +1,655 @@ +package lime.tools; + + +import haxe.xml.Fast; +import hxp.Log; +import hxp.ObjectHelper; + + +abstract ConfigData(Dynamic) to Dynamic from Dynamic { + + + public function new () { + + this = { }; + + } + + + private function addBucket (bucket:String, parent:Dynamic):Dynamic { + + if (!Reflect.hasField (parent, bucket)) { + + log ("config data > adding a bucketType " + bucket); + Reflect.setField (parent, bucket, { }); + + } + + return Reflect.field (parent, bucket); + + } + + + public function clone ():ConfigData { + + return ObjectHelper.deepCopy (this); + + } + + + public function exists (id:String):Bool { + + var tree = id.split ('.'); + + if (tree.length <= 1) { + + return Reflect.hasField (this, id); + + } + + var current = this; + + for (leaf in tree) { + + if (Reflect.hasField (current, leaf)) { + + current = Reflect.field (current, leaf); + + } else { + + return false; + + } + + } + + return true; + + } + + + public function get (id:String):ConfigData { + + var tree = id.split ('.'); + + if (tree.length <= 1) { + + return Reflect.field (this, id); + + } + + var current = this; + + for (leaf in tree) { + + current = Reflect.field (current, leaf); + + if (current == null) { + + return null; + + } + + } + + return current; + + } + + + public function getArray (id:String, defaultValue:Array = null):Array { + + var tree = id.split ('.'); + var array:Array = null; + + if (tree.length <= 1) { + + array = Reflect.field (this, id + "___array"); + + if (array == null && Reflect.hasField (this, id)) { + + array = [ Reflect.field (this, id) ]; + + } + + } else { + + var current = this; + var field = tree.pop (); + + for (leaf in tree) { + + current = Reflect.field (current, leaf); + + if (current == null) { + + break; + + } + + } + + if (current != null) { + + array = Reflect.field (current, field + "___array"); + + if (array == null && Reflect.hasField (current, field)) { + + array = [ Reflect.field (current, field) ]; + + } + + } + + } + + if (array != null) { + + return array; + + } + + if (defaultValue == null) { + + defaultValue = []; + + } + + return defaultValue; + + } + + + public function getArrayString (id:String, childField:String = null, defaultValue:Array = null):Array { + + var array = getArray (id); + + if (array.length > 0) { + + var value = []; + + if (childField == null) { + + for (item in array) { + + value.push (Std.string (item)); + + } + + } else { + + for (item in array) { + + value.push (Std.string (Reflect.field (item, childField))); + + } + + } + + return value; + + } + + if (defaultValue == null) { + + defaultValue = []; + + } + + return defaultValue; + + } + + + public function getBool (id:String, defaultValue:Bool = true):Bool { + + if (exists (id)) { + + return get (id) == "true"; + + } + + return defaultValue; + + } + + + public function getInt (id:String, defaultValue:Int = 0):Int { + + if (exists (id)) { + + return Std.parseInt (Std.string (get (id))); + + } + + return defaultValue; + + } + + + public function getFloat (id:String, defaultValue:Float = 0):Float { + + if (exists (id)) { + + return Std.parseFloat (Std.string (get (id))); + + } + + return defaultValue; + + } + + + public function getString (id:String, defaultValue:String = ""):String { + + if (exists (id)) { + + return Std.string (get (id)); + + } + + return defaultValue; + + } + + + private function log (v:Dynamic):Void { + + if (Log.verbose) { + + //Log.println (v); + + } + + } + + + public function merge (other:ConfigData):Void { + + if (other != null) { + + mergeValues (other, this); + + } + + } + + + private function mergeValues (source:T, destination:T):Void { + + for (field in Reflect.fields (source)) { + + if (StringTools.endsWith (field, "___array")) { + + continue; + + } + + var doCopy = true; + var exists = Reflect.hasField (destination, field); + var typeDest = null; + + if (exists) { + + var valueSource = Reflect.field (source, field); + var valueDest = Reflect.field (destination, field); + var typeSource = Type.typeof(valueSource).getName (); + typeDest = Type.typeof (valueDest).getName (); + + //if trying to copy a non object over an object, don't + if (typeSource != "TObject" && typeDest == "TObject") { + + doCopy = false; + + //if (Log.verbose) { + // + //Log.println (field + " not merged by preference"); + // + //} + + } + + if (doCopy && Reflect.field (source, field) != Reflect.field (destination, field) && typeSource != "TObject") { + + if (!Reflect.hasField (destination, field + "___array")) { + + Reflect.setField (destination, field + "___array", [ ObjectHelper.deepCopy (Reflect.field (destination, field)) ]); + + } + + var array:Array = Reflect.field (destination, field + "___array"); + + if (Reflect.hasField (source, field + "___array")) { + + array = array.concat (Reflect.field (source, field + "___array")); + Reflect.setField (destination, field + "___array", array); + + } else { + + array.push (Reflect.field (source, field)); + + } + + Reflect.setField (destination, field, Reflect.field (source, field)); + doCopy = false; + + } + + } + + if (doCopy) { + + if (typeDest == "TObject") { + + mergeValues (Reflect.field (source, field), Reflect.field (destination, field)); + + } else { + + Reflect.setField (destination, field, Reflect.field (source, field)); + + if (Reflect.hasField (source, field + "___array")) { + + Reflect.setField (destination, field + "___array", Reflect.field (source, field + "___array")); + + } + + } + + } + + } + + } + + + public function parse (elem:Fast, substitute:String->String = null):Void { + + var bucket = this; + var bucketType = ""; + + if (StringTools.startsWith (elem.name, "config:")) { + + var items = elem.name.split(':'); + bucketType = items[1]; + + } + + if (elem.has.type) { + + bucketType = elem.att.type; + + } + + if (bucketType != "") { + + bucket = addBucket (bucketType, this); + + } + + parseAttributes (elem, bucket, substitute); + parseChildren (elem, bucket, 0, substitute); + + log ("> current config : " + this); + + } + + + private function parseAttributes (elem:Fast, bucket:Dynamic, substitute:String->String = null):Void { + + for (attrName in elem.x.attributes ()) { + + if (attrName != "type") { + + var attrValue = elem.x.get (attrName); + if (substitute != null) attrValue = substitute (attrValue); + setNode (bucket, attrName, attrValue); + + } + + } + + } + + + private function parseChildren (elem:Fast, bucket:Dynamic, depth:Int = 0, substitute:String->String = null):Void { + + for (child in elem.elements) { + + if (child.name != "config") { + + // log("config data > child : " + child.name); + + var d = depth + 1; + + var hasChildren = child.x.elements ().hasNext (); + var hasAttributes = child.x.attributes ().hasNext (); + + if (Reflect.hasField (bucket, child.name)) { + + if (!Reflect.hasField (bucket, child.name + "___array")) { + + Reflect.setField (bucket, child.name + "___array", [ ObjectHelper.deepCopy (Reflect.field (bucket, child.name)) ]); + + } + + var array:Array = Reflect.field (bucket, child.name + "___array"); + var arrayBucket = { }; + array.push (arrayBucket); + + if (hasAttributes) { + + parseAttributes (child, arrayBucket, substitute); + + } + + if (hasChildren) { + + parseChildren (child, arrayBucket, d, substitute); + + } + + if (!hasChildren && !hasAttributes) { + + parseValue (child, arrayBucket, substitute); + + } + + } + + if (!hasChildren && !hasAttributes) { + + parseValue (child, bucket, substitute); + + } else { + + var childBucket = addBucket (child.name, bucket); + + if (hasAttributes) { + + parseAttributes (child, childBucket, substitute); + + } + + if (hasChildren) { + + parseChildren (child, childBucket, d, substitute); + + } + + } + + } + } + + } + + + private function parseValue (elem:Fast, bucket:Dynamic, substitute:String->String = null):Void { + + if (elem.innerHTML != "") { + + var value = elem.innerHTML; + if (substitute != null) value = substitute (value); + setNode (bucket, elem.name, value); + + } + + } + + + public function push (id:String, value:Dynamic):Void { + + var tree = id.split ('.'); + + if (tree.length <= 1) { + + if (Reflect.hasField (this, id)) { + + if (!Reflect.hasField (this, id + "___array")) { + + Reflect.setField (this, id + "___array", Reflect.hasField (this, id) ? [ ObjectHelper.deepCopy (Reflect.field (this, id)) ] : []); + + } + + var array:Array = Reflect.field (this, id + "___array"); + array.push (value); + + } + + Reflect.setField (this, id, value); + return; + + } + + var current = this; + var field = tree.pop (); + + for (leaf in tree) { + + if (!Reflect.hasField (current, leaf)) { + + Reflect.setField (current, leaf, {}); + current = Reflect.field (current, leaf); + + } else { + + current = Reflect.field (current, leaf); + + if (current == null) { + + return; + + } + + } + + } + + if (Reflect.hasField (current, field)) { + + if (!Reflect.hasField (current, field + "___array")) { + + Reflect.setField (current, field + "___array", Reflect.hasField (current, field) ? [ ObjectHelper.deepCopy (Reflect.field (current, field)) ] : []); + + } + + var array:Array = Reflect.field (current, field + "___array"); + array.push (value); + + } + + Reflect.setField (current, field, value); + + } + + + public function set (id:String, value:Dynamic):Void { + + var tree = id.split ('.'); + + if (tree.length <= 1) { + + Reflect.setField (this, id, value); + return; + + } + + var current = this; + var field = tree.pop (); + + for (leaf in tree) { + + if (!Reflect.hasField (current, leaf)) { + + Reflect.setField (current, leaf, {}); + current = Reflect.field (current, leaf); + + } else { + + current = Reflect.field (current, leaf); + + if (current == null) { + + return; + + } + + } + + } + + Reflect.setField (current, field, value); + + } + + + private function setNode (bucket:Dynamic, node:String, value:Dynamic):Void { + + // log("config data > setting a node " + node + " to " + value + " on " + bucket); + + var doCopy = true; + var exists = Reflect.hasField (bucket, node); + + if (exists) { + + var valueDest = Reflect.field (bucket, node); + var typeSource = Type.typeof (value).getName (); + var typeDest = Type.typeof (valueDest).getName (); + + // trace (node + " / existed in dest as " + typeDest + " / " + typeSource ); + + if (typeSource != "TObject" && typeDest == "TObject") { + + doCopy = false; + log (node + " not merged by preference over object"); + + } + + if (doCopy) { + + if (typeSource != "TObject") { + + if (!Reflect.hasField (bucket, node + "___array")) { + + Reflect.setField (bucket, node + "___array", [ ObjectHelper.deepCopy (Reflect.field (bucket, node)) ]); + + } + + cast (Reflect.field (bucket, node + "___array"), Array).push (value); + + } + + Reflect.setField (bucket, node, value); + + } + + } else { + + Reflect.setField (bucket, node, value); + + } + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/ConfigHelper.hx b/src/lime/tools/ConfigHelper.hx new file mode 100644 index 000000000..1f7d2a710 --- /dev/null +++ b/src/lime/tools/ConfigHelper.hx @@ -0,0 +1,397 @@ +package lime.tools; + + +import haxe.io.Path; +import lime.tools.Project; +import lime.tools.Platform; +import hxp.*; +import lime.tools.ProjectXMLParser; +import sys.io.File; +import sys.FileSystem; + + +class ConfigHelper { + + + private static var backedUpConfig:Bool = false; + private static var configPath:String = null; + + + public static function getConfig ():Project { + + var config = getConfigPath (); + + if (FileSystem.exists (config)) { + + Log.info ("", Log.accentColor + "Reading HXP config: " + config + Log.resetColor); + + return new ProjectXMLParser (config); + + } else { + + Log.warn ("", "Could not read HXP config: " + config); + + } + + return null; + + } + + + public static function getConfigPath ():String { + + if (configPath == null) { + + var environment = Sys.environment (); + + if (environment.exists ("HXP_CONFIG")) { + + configPath = environment.get ("HXP_CONFIG"); + + } else { + + var home = ""; + + if (environment.exists ("HOME")) { + + home = environment.get ("HOME"); + + } else if (environment.exists ("USERPROFILE")) { + + home = environment.get ("USERPROFILE"); + + } else { + + Log.warn ("HXP config might be missing (Environment has no \"HOME\" variable)"); + + return null; + + } + + configPath = home + "/.hxp/config.xml"; + + if (PlatformHelper.hostPlatform == WINDOWS) { + + configPath = configPath.split ("/").join ("\\"); + + } + + if (!FileSystem.exists (configPath)) { + + var limeConfig = home + "/.lime/config.xml"; + + if (FileSystem.exists (limeConfig)) { + + FileHelper.copyFile (limeConfig, configPath); + + } + + } + + if (!FileSystem.exists (configPath)) { + + PathHelper.mkdir (Path.directory (configPath)); + + var hxcppConfig = null; + + if (environment.exists ("HXCPP_CONFIG")) { + + hxcppConfig = environment.get ("HXCPP_CONFIG"); + + } else { + + hxcppConfig = home + "/.hxcpp_config.xml"; + + } + + if (FileSystem.exists (hxcppConfig)) { + + var vars = new ProjectXMLParser (hxcppConfig); + + for (key in vars.defines.keys ()) { + + if (key != key.toUpperCase ()) { + + vars.defines.remove (key); + + } + + } + + writeConfig (configPath, vars.defines); + + } else { + + writeConfig (configPath, new Map ()); + + } + + } + + Sys.putEnv ("LIME_CONFIG", configPath); + + } + + } + + return configPath; + + } + + + public static function getConfigValue (name:String):String { + + var config = getConfig (); + + if (config.defines.exists (name)) { + + return config.defines.get (name); + + } + + return null; + + } + + + public static function removeConfigValue (name:String):Void { + + var path = getConfigPath (); + + if (FileSystem.exists (path)) { + + var configText = File.getContent (path); + var lines = configText.split ("\n"); + + var findSet = " -1) { + + found = true; + lines.splice (i, 1); + continue; + + } + + if ((index = line.indexOf (findSetenv)) > -1) { + + found = true; + lines.splice (i, 1); + continue; + + } + + if ((index = line.indexOf (findDefine)) > -1) { + + found = true; + lines.splice (i, 1); + continue; + + } + + i++; + + } + + var content = lines.join ("\n"); + File.saveContent (path, content); + + if (found) { + + Log.info ("Removed define \"" + name + "\""); + + } else { + + Log.info ("There is no define \"" + name + "\""); + + } + + } else { + + Log.error ("Cannot find \"" + path + "\""); + + } + + } + + + private static function stripQuotes (path:String):String { + + if (path != null) { + + return path.split ("\"").join (""); + + } + + return path; + + } + + + public static function writeConfig (path:String, defines:Map):Void { + + var newContent = ""; + var definesText = ""; + var env = Sys.environment (); + + for (key in defines.keys ()) { + + if (key != "LIME_CONFIG" && key != "LIME_CONFIG" && (!env.exists (key) || env.get (key) != defines.get (key))) { + + definesText += "\t\t\n"; + + } + + } + + if (FileSystem.exists (path)) { + + var input = File.read (path, false); + var bytes = input.readAll (); + input.close (); + + if (!backedUpConfig) { + + try { + + var backup = File.write (path + ".bak", false); + backup.writeBytes (bytes, 0, bytes.length); + backup.close (); + + } catch (e:Dynamic) { } + + backedUpConfig = true; + + } + + var content = bytes.getString (0, bytes.length); + + var startIndex = content.indexOf ("
"); + var endIndex = content.indexOf ("
", startIndex); + + newContent += content.substr (0, startIndex) + "
\n\t\t\n"; + newContent += definesText; + newContent += "\t\t\n\t" + content.substr (endIndex); + + } else { + + newContent += "\n"; + newContent += "\n\t\n"; + newContent += "\t
\n\t\t\n"; + newContent += definesText; + newContent += "\t\t\n\t
\n\t\n
"; + + } + + var output = File.write (path, false); + output.writeString (newContent); + output.close (); + + if (backedUpConfig) { + + try { + + FileSystem.deleteFile (path + ".bak"); + + } catch (e:Dynamic) {} + + } + + } + + + public static function writeConfigValue (name:String, value:String):Void { + + var path = getConfigPath (); + + try { + + if (!FileSystem.exists (value) && FileSystem.exists (PathHelper.expand (value))) { + + value = PathHelper.expand (value); + + } + + } catch (e:Dynamic) {} + + if (FileSystem.exists (path)) { + + var configText = File.getContent (path); + var lines = configText.split ("\n"); + + var findSet = " -1) { + + found = true; + lines[i] = line.substr (0, index) + ""; + + } + + if ((index = line.indexOf (findSetenv)) > -1) { + + found = true; + lines[i] = line.substr (0, index) + ""; + + } + + if ((index = line.indexOf (findDefine)) > -1) { + + found = true; + lines[i] = line.substr (0, index) + ""; + + } + + i++; + + } + + if (!found && lines.length > 2) { + + var insertPoint = lines.length - 3; + + if (StringTools.trim (lines[lines.length - 1]) == "") { + + insertPoint--; + + } + + if (StringTools.trim (lines[insertPoint + 1]) != "") { + + lines.insert (insertPoint + 1, "\t"); + + } + + lines.insert (insertPoint + 1, "\t"); + + } + + var content = lines.join ("\n"); + File.saveContent (path, content); + + Log.info ("Set \x1b[1m" + name + "\x1b[0m to \x1b[1m" + value + "\x1b[0m"); + + } else { + + Log.error ("Cannot find \"" + path + "\""); + + } + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/Dependency.hx b/src/lime/tools/Dependency.hx new file mode 100644 index 000000000..871aace97 --- /dev/null +++ b/src/lime/tools/Dependency.hx @@ -0,0 +1,31 @@ +package lime.tools; + + +class Dependency { + + + // TODO: Is "forceLoad" the best name? Implement "whole-archive" on GCC + + public var forceLoad:Bool; + public var name:String; + public var path:String; + + + public function new (name:String, path:String) { + + this.name = name; + this.path = path; + + } + + + public function clone ():Dependency { + + var dependency = new Dependency (name, path); + dependency.forceLoad = forceLoad; + return dependency; + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/DeploymentHelper.hx b/src/lime/tools/DeploymentHelper.hx new file mode 100644 index 000000000..b22a9bb8f --- /dev/null +++ b/src/lime/tools/DeploymentHelper.hx @@ -0,0 +1,45 @@ +package lime.tools; + + +import hxp.*; +import lime.tools.Project; + + +class DeploymentHelper { + + + public static function deploy (project:Project, targetFlags:Map, targetDirectory:String, targetName:String) { + + var name = project.meta.title + " (" + project.meta.version + " build " + project.meta.buildNumber + ") (" + targetName + ").zip"; + var targetPath = PathHelper.combine (targetDirectory + "/dist", name); + + ZipHelper.compress (PathHelper.combine (targetDirectory, "bin"), targetPath); + + if (targetFlags.exists ("gdrive")) { + + var parent = targetFlags.get ("parent"); + + var args = [ "upload" , "-f" , targetPath ]; + + if (targetFlags.exists("config")) { + + args.push ("--config"); + args.push (targetFlags.get("config")); + + } + + if (parent != null && parent != "") { + + args.push ("-p"); + args.push (parent); + + } + + ProcessHelper.runCommand ("", "drive", args); + + } + + } + + +} diff --git a/src/lime/tools/ElectronHelper.hx b/src/lime/tools/ElectronHelper.hx new file mode 100644 index 000000000..be54329ee --- /dev/null +++ b/src/lime/tools/ElectronHelper.hx @@ -0,0 +1,31 @@ +package lime.tools; + + +import hxp.PathHelper; +import hxp.ProcessHelper; +import lime.tools.Project; + + +class ElectronHelper { + + + public static function launch (project:Project, path:String):Void { + + var electronPath = project.defines.get ("ELECTRON_PATH"); + + if (electronPath == null || electronPath == "") { + + electronPath = "electron"; + + } else { + + electronPath = PathHelper.combine (electronPath, "electron"); + + } + + ProcessHelper.runCommand ("", electronPath, [ path ]); + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/FlashHelper.hx b/src/lime/tools/FlashHelper.hx new file mode 100644 index 000000000..0961e4781 --- /dev/null +++ b/src/lime/tools/FlashHelper.hx @@ -0,0 +1,1059 @@ +package lime.tools; + + +//import openfl.text.Font; +//import openfl.utils.ByteArray; +import haxe.io.Bytes; +import haxe.io.Path; +import lime.tools.Asset; +import lime.tools.AssetEncoding; +import lime.tools.AssetType; +import lime.tools.Project; +#if (lime && lime_cffi && !macro) +import lime.text.Font; +#end +import hxp.Log; +import hxp.ProcessHelper; +import hxp.*; +import sys.io.File; +import sys.FileSystem; +import sys.io.FileSeek; + +#if format +import format.swf.Data; +import format.swf.Constants; +import format.swf.Reader; +import format.swf.Writer; +import format.wav.Data; +#end + + +class FlashHelper { + + + private static var swfAssetID = 1000; + + + #if format + private static function embedAsset (inAsset:Asset, packageName:String, outTags:Array) { + + var embed = inAsset.embed; + var path = inAsset.sourcePath; + var type = inAsset.type; + var flatName = inAsset.flatName; + var ext = inAsset.format; + var name = (path == null || path == "") ? inAsset.targetPath : path; + + if (embed == false) { + + return false; + + } + + Log.info ("", " - \x1b[1mEmbedding asset:\x1b[0m \x1b[3;37m(" + type + ")\x1b[0m " + name); + + var cid = nextAssetID (); + + if (type == AssetType.MUSIC || type == AssetType.SOUND) { + + var src = path; + + if (ext != "mp3" && ext != "wav") { + + for (e in ["wav", "mp3"]) { + + src = path.substr (0, path.length - ext.length) + e; + + if (FileSystem.exists (src)) { + + break; + + } + + } + + } + + if (!FileSystem.exists (src)) { + + Sys.println ("Warning: Could not embed unsupported audio file \"" + name + "\", embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + + } + + var input = File.read (src, true); + + if (ext == "mp3") { + + var reader = new mpeg.audio.MpegAudioReader(input); + + var frameDataWriter = new haxe.io.BytesOutput(); + var totalLengthSamples = 0; + var samplingFrequency = -1; + var isStereo:Null = null; + var encoderDelay = 0; + var endPadding = 0; + var decoderDelay = 529; // This is a constant delay caused by the Fraunhofer MP3 Decoder used in Flash Player. + + while (true) { + switch (reader.readNext()) { + case Frame(frame): + if (frame.header.layer != mpeg.audio.Layer.Layer3) { + Sys.println ("Warning: Could not embed \"" + name + "\" (Flash only supports Layer-III MP3 files, but file is " + frame.header.layer + "), embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + } + var frameSamplingFrequency = frame.header.samplingFrequency; + if (samplingFrequency == -1) { + samplingFrequency = frameSamplingFrequency; + } else if (frameSamplingFrequency != samplingFrequency) { + Sys.println ("Warning: Could not embed \"" + name + "\" (Flash does not support MP3 audio with variable sampling frequencies), embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + } + var frameIsStereo = frame.header.mode != mpeg.audio.Mode.SingleChannel; + if (isStereo == null) { + isStereo = frameIsStereo; + } else if (frameIsStereo != isStereo) { + Sys.println ("Warning: Could not embed \"" + name + "\" (Flash does not support MP3 audio with mixed mono and stero frames), embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + } + frameDataWriter.write(frame.frameData); + totalLengthSamples += mpeg.audio.Utils.lookupSamplesPerFrame(frame.header.version, frame.header.layer); + + case GaplessInfo(giEncoderDelay, giEndPadding): + encoderDelay = giEncoderDelay; + endPadding = giEndPadding; + + case Info(_): // ignore + case Unknown(_): // ignore + case End: break; + } + } + + if (totalLengthSamples == 0) { + Sys.println ("Warning: Could not embed \"" + name + "\" (Could not find any valid MP3 audio data), embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + } + + var flashSamplingFrequency = switch (samplingFrequency) { + case 11025: SR11k; + case 22050: SR22k; + case 44100: SR44k; + default: null; + } + + if (flashSamplingFrequency == null) { + + Sys.println ("Warning: Could not embed \"" + name + "\" (Flash supports 11025, 22050 and 44100kHz MP3 files, but file is " + samplingFrequency + "kHz), embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + + } + + var frameData = frameDataWriter.getBytes(); + + var snd:format.swf.Sound = { + sid: cid, + format: SFMP3, + rate: flashSamplingFrequency, + is16bit: true, + isStereo: isStereo, + samples: totalLengthSamples - endPadding - encoderDelay, + data: SDMp3(encoderDelay + decoderDelay, frameData) + }; + + outTags.push (TSound (snd)); + + } else { + + var header = input.readString (4); + + if (ext == "ogg" || header == "OggS") { + + Sys.println ("Warning: Skipping unsupported OGG file \"" + name + "\", embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + + } else if (header != "RIFF") { + + Sys.println ("Warning: Could not embed unrecognized WAV file \"" + name + "\", embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + + } else { + + input.close (); + input = File.read (src, true); + + var r = new format.wav.Reader (input); + var wav = r.read (); + var hdr = wav.header; + + if (hdr.format != WF_PCM) { + + Sys.println ("Warning: Could not embed \"" + name + "\" (Only PCM uncompressed WAV files are currently supported), embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + + } + + // Check sampling rate + var flashRate = switch (hdr.samplingRate) { + + case 5512: SR5k; + case 11025: SR11k; + case 22050: SR22k; + case 44100: SR44k; + default: null; + + } + + if (flashRate == null) { + + Sys.println ("Warning: Could not embed \"" + name + "\" (Flash supports 5512, 11025, 22050 and 44100kHz WAV files, but file is " + hdr.samplingRate + "kHz), embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + + } + + var isStereo = switch (hdr.channels) { + + case 1: false; + case 2: true; + default: + throw "Number of channels should be 1 or 2, but for '" + src + "' it is " + hdr.channels; + + } + + var is16bit = switch (hdr.bitsPerSample) { + + case 8: false; + case 16: true; + default: + throw "Bits per sample should be 8 or 16, but for '" + src + "' it is " + hdr.bitsPerSample; + + } + + if (wav.data != null) { + + var sampleCount = Std.int (wav.data.length / (hdr.bitsPerSample / 8)); + + var snd:format.swf.Sound = { + + sid : cid, + format : SFLittleEndianUncompressed, + rate : flashRate, + is16bit : is16bit, + isStereo : isStereo, + samples : sampleCount, + data : SDRaw (wav.data) + + } + + outTags.push (TSound (snd)); + + } else { + + Sys.println ("Warning: Could not embed WAV file \"" + name + "\", the file may be corrupted, embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + + } + + } + + } + + input.close (); + + } else if (type == AssetType.IMAGE) { + + if (inAsset.data != null) { + + if (inAsset.encoding == AssetEncoding.BASE64) { + + outTags.push (TBitsJPEG (cid, JDJPEG2 (StringHelper.base64Decode (inAsset.data)))); + + } else { + + outTags.push (TBitsJPEG (cid, JDJPEG2 (inAsset.data))); + + } + + } else { + + var src = path; + + if (ext == "jpg" || ext == "jpeg" || ext == "png" || ext == "gif") { + + if (!FileSystem.exists (src)) { + + Sys.println ("Warning: Could not find image path \"" + src + "\""); + + } else { + + var bytes = File.getBytes (src); + outTags.push (TBitsJPEG (cid, JDJPEG2 (bytes))); + + } + + } else { + + Sys.println ("Warning: Could not embed image file \"" + name + "\", unknown image type, embedding as binary"); + inAsset.type = BINARY; + return embedAsset (inAsset, packageName, outTags); + + } + + } + + } else if (type == AssetType.FONT) { + + // More code ripped off from "samhaxe" + + #if (lime && lime_cffi && !macro) + var src = path; + var face = Font.fromFile (src); + var font = face.decompose (); + var font_name = font.family_name; + //fallback for font name is case no one could be found.. + if ( font_name == null || font_name.length == 0 ) + font_name = Path.withoutExtension(name).split("/").pop().split("\\").pop(); + + var glyphs = new Array (); + var glyph_layout = new Array (); + + for (native_glyph in font.glyphs) { + + if (native_glyph.char_code > 65535) { + + Sys.println("Warning: glyph with character code greater than 65535 encountered ("+ native_glyph.char_code+"). Skipping..."); + continue; + + } + + var shapeRecords = new Array (); + var i:Int = 0; + var styleChanged:Bool = false; + var dx = 0; + var dy = 0; + + while (i < native_glyph.points.length) { + + var type = native_glyph.points[i++]; + + switch (type) { + + case 1: // Move + + dx = native_glyph.points[i++]; + dy = native_glyph.points[i++]; + shapeRecords.push( SHRChange({ + moveTo: {dx: dx, dy: -dy}, + // Set fill style to 1 in first style change record + // Required by DefineFontX + fillStyle0: if (!styleChanged) {idx: 1} else null, + fillStyle1: null, + lineStyle: null, + newStyles: null + })); + styleChanged = true; + + case 2: // LineTo + + dx = native_glyph.points[i++]; + dy = native_glyph.points[i++]; + shapeRecords.push (SHREdge(dx, -dy)); + + case 3: // CurveTo + var cdx = native_glyph.points[i++]; + var cdy = native_glyph.points[i++]; + dx = native_glyph.points[i++]; + dy = native_glyph.points[i++]; + shapeRecords.push (SHRCurvedEdge(cdx, -cdy, dx, -dy)); + + case 4: // CubicCurveTo + var p1x = native_glyph.points[i++]; + var p1y = native_glyph.points[i++]; + var p2x = native_glyph.points[i++]; + var p2y = native_glyph.points[i++]; + var p3x = native_glyph.points[i++]; + var p3y = native_glyph.points[i++]; + + // Get original points + + var cp1x = p1x + dx; + var cp1y = p1y + dy; + var cp2x = p2x + cp1x; + var cp2y = p2y + cp1y; + var endx = p3x + cp2x; + var endy = p3y + cp2y; + + // Convert to quadratic + + var cpx = Std.int ((-0.25 * dx) + (0.75 * cp1x) + (0.75 * cp2x) + ( -0.25 * endx)); + var cpy = Std.int (( -0.25 * dy) + (0.75 * cp1y) + (0.75 * cp2y) + ( -0.25 * endy)); + + // Offset again + + var cdx = cpx - dx; + var cdy = cpy - dy; + dx = endx - cpx; + dy = endy - cpy; + + shapeRecords.push (SHRCurvedEdge(cdx, -cdy, dx, -dy)); + + default: + throw "Invalid control point type encountered! (" + type + ")"; + + } + + } + + shapeRecords.push (SHREnd); + + glyphs.push({ + charCode: native_glyph.char_code, + shape: { + shapeRecords: shapeRecords + } + }); + + glyph_layout.push({ + advance: native_glyph.advance, + bounds: { + left: native_glyph.min_x, + right: native_glyph.max_x, + top: -native_glyph.max_y, + bottom: -native_glyph.min_y, + } + }); + + } + + var kerning = new Array (); + + if (font.kerning != null) { + + var length = font.kerning.length; + if (length > 0xFFFF) length = 0xFFFF; + var k; + + for (i in 0...length) { + + k = font.kerning[i]; + + kerning.push ({ + charCode1: k.left_glyph, + charCode2: k.right_glyph, + adjust: k.x, + }); + + } + + } + + var swf_em = 1024 * 20; + var ascent = Math.round (Math.abs (font.ascend * swf_em / font.em_size)); + var descent = Math.round (Math.abs ((font.descend) * swf_em / font.em_size)); + var leading = Math.round ((font.height - font.ascend + font.descend) * swf_em / font.em_size); + var language = LangCode.LCNone; + + outTags.push (TFont (cid, FDFont3 ({ + shiftJIS: false, + isSmall: false, + isANSI: false, + isItalic: font.is_italic, + isBold: font.is_bold, + language: language, + name: font_name, + glyphs: glyphs, + layout: { + ascent: ascent, + descent: descent, + leading: leading, + glyphs: glyph_layout, + kerning: kerning + } + })) ); + #end + + } else { + + var bytes:Bytes = null; + + if (inAsset.data != null) { + + if (inAsset.encoding == AssetEncoding.BASE64) { + + bytes = StringHelper.base64Decode (inAsset.data); + + } else if (Std.is (inAsset.data, Bytes)) { + + bytes = cast inAsset.data; + + } else { + + bytes = Bytes.ofString (Std.string (inAsset.data)); + + } + + } + + if (bytes == null) { + + bytes = File.getBytes (path); + + } + + outTags.push (TBinaryData (cid, bytes)); + + } + + outTags.push (TSymbolClass ( [ { cid:cid, className: packageName + "__ASSET__" + flatName } ] )); + + return true; + + } + #end + + + /*public static function embedAssets (targetPath:String, assets:Array, packageName:String = ""):Void { + + try { + + var input = File.read (targetPath, true); + + if (input != null) { + + var reader = new Reader (input); + var swf = reader.read (); + input.close(); + + var new_tags = new Array (); + var inserted = false; + + for (tag in swf.tags) { + + var name = Type.enumConstructor (tag); + + if (name == "TShowFrame" && !inserted && assets.length > 0) { + + new_tags.push (TShowFrame); + + for (asset in assets) { + + try { + + if (asset.type != AssetType.TEMPLATE && embedAsset (asset, packageName, new_tags)) { + + inserted = true; + + } + + } catch (e:Dynamic) { + + Sys.println ("Error embedding \"" + asset.sourcePath + "\": " + e); + + } + + } + + } + + new_tags.push (tag); + + } + + if (inserted) { + + swf.tags = new_tags; + var output = File.write (targetPath, true); + var writer = new Writer (output); + writer.write (swf); + output.close (); + + } + + } else { + + trace ("Embedding assets failed! We encountered an error. Does '" + targetPath + "' exist?"); + + } + + } catch (e:Dynamic) { + + trace ("Embedding assets failed! We encountered an error accessing '" + targetPath + "': " + e); + + } + + }*/ + + + public static function enableLogging ():Void { + + try { + + var path = switch (PlatformHelper.hostPlatform) { + + case WINDOWS: Sys.getEnv ("HOMEDRIVE") + "/" + Sys.getEnv ("HOMEPATH") + "/mm.cfg"; + //case MAC: "/Library/Application Support/Macromedia/mm.cfg"; + default: Sys.getEnv ("HOME") + "/mm.cfg"; + + } + + if (!FileSystem.exists (path)) { + + File.saveContent (path, "ErrorReportingEnable=1\nTraceOutputFileEnable=1\nMaxWarnings=50"); + + } + + } catch (e:Dynamic) {} + + } + + + private static function compileSWC (project:Project, assets:Array, id:Int, destination:String):Void { + + #if format + destination = destination + "/obj"; + PathHelper.mkdir (destination); + + var label = (id > 0 ? Std.string (id + 1) : ""); + + var swfVersions = [ 9, 10, /*10.1,*/ 10.2, 10.3, 11, 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 12, 13, 14 ]; + + var flashVersion = 9; + + if (project.app.swfVersion > 14) { + + flashVersion += Std.int ((swfVersions.length - 1) + (project.app.swfVersion - 14)); + + } else { + + for (swfVersion in swfVersions) { + + if (project.app.swfVersion > swfVersion) { + + flashVersion++; + + } + + } + + } + + var header:SWFHeader = + { + version : flashVersion, + compressed : true, + width : (project.window.width == 0 ? 800 : project.window.width), + height : (project.window.height == 0 ? 500 : project.window.height), + fps : project.window.fps * 256, + nframes : project.target == AIR ? 1 : 2 + }; + + var tags = new Array (); + var packageName = ""; + var inserted = false; + + tags.push (TBackgroundColor (project.window.background)); + + if (project.target != AIR) { + + tags.push (TShowFrame); + + } + + // Might generate ABC later, so we don't need the @:bind calls in DefaultAssetLibrary? + + /*var abc = new haxe.io.BytesOutput (); + var abcWriter = new format.abc.Writer (abc); + + for (asset in assets) { + + var classDef:ClassDef = { + var name : packageName + "__ASSET__" + asset.flatName; + var superclass : asset.flashClass; + var interfaces : []]; + var constructor : null; + var fields : []; + var namespace : null; + var isSealed : false; + var isFinal : false; + var isInterface : false; + var statics : []; + var staticFields : []; + } + abcWriter.writeClass (classDef); + + }*/ + + for (asset in assets) { + + #if format + try { + + if (asset.type != AssetType.TEMPLATE && embedAsset (asset, packageName, tags)) { + + inserted = true; + + } + + } catch (e:Dynamic) { + + Sys.println ("Error embedding \"" + asset.sourcePath + "\": " + e); + + } + #end + + } + + tags.push (TShowFrame); + + if (inserted) { + + var swf:SWF = { header: header, tags: tags }; + var output = File.write (destination + "/assets.swf", true); + var writer = new Writer (output); + writer.write (swf); + output.close (); + + } + #end + + } + + + /*private static function compileSWC (project:Project, embed:String, id:Int):Void { + + var destination = project.app.path + "/flash/obj"; + PathHelper.mkdir (destination); + + var label = (id > 0 ? Std.string (id + 1) : ""); + + File.saveContent (destination + "/EmbeddedAssets.hx", embed); + var args = [ "EmbeddedAssets", "-cp", destination, "-D", "swf-preloader-frame", "-swf", destination + "/assets.swf" ]; + + if (id == 0) { + + var header = args.push ("-swf-header"); + args.push ((project.window.width == 0 ? 800 : project.window.width) + ":" + (project.window.height == 0 ? 500 : project.window.height) + ":" + project.window.fps + ":" + StringTools.hex (project.window.background, 6)); + + } else { + + if (FileSystem.exists (destination + "/assets.swf")) { + + FileHelper.copyFile (destination + "/assets.swf", destination + "/.assets.swf"); + + } + + // Have to daisy-chain it to fix Haxe compiler issue + + args.push ("-swf-lib"); + args.push (destination + "/.assets.swf"); + args.push ("-D"); + args.push ("flash-use-stage"); + + } + + ProcessHelper.runCommand ("", "haxe", args); + + if (FileSystem.exists (destination + "/.assets.swf")) { + + try { + + FileSystem.deleteFile (destination + "/.assets.swf"); + + } catch (e:Dynamic) {} + + } + + }*/ + + + public static function embedAssets (project:Project, targetDirectory:String):Bool { + + var embed = ""; + var assets = []; + var maxSize = 1024 * 1024 * 16; + var currentSize = 0; + var id = 0; + var tempFiles = []; + + for (asset in project.assets) { + + if (asset.embed == null || asset.embed == true) { + + //Log.info ("", " - \x1b[1mEmbedding asset:\x1b[0m \x1b[3;37m(" + asset.type + ")\x1b[0m " + asset.sourcePath); + + var flashClass = switch (asset.type) { + + case MUSIC: "flash.media.Sound"; + case SOUND: "flash.media.Sound"; + case IMAGE: "flash.display.BitmapData"; + case FONT: "flash.text.Font"; + default: "flash.utils.ByteArray"; + + } + + var tagName = switch (asset.type) { + + case MUSIC: "@:sound"; + case SOUND: "@:sound"; + case IMAGE: "@:bitmap"; + case FONT: "@:font"; + default: "@:file"; + + } + + var ignoreAsset = false; + var sourcePath = null; + + if (asset.data != null) { + + sourcePath = PathHelper.getTemporaryFile (); + tempFiles.push (sourcePath); + + if (asset.encoding == AssetEncoding.BASE64) { + + File.saveBytes (sourcePath, StringHelper.base64Decode (asset.data)); + + } else if (Std.is (asset.data, Bytes)) { + + File.saveBytes (sourcePath, asset.data); + + } else { + + File.saveContent (sourcePath, Std.string (asset.data)); + + } + + } else { + + sourcePath = asset.sourcePath; + + } + + try { + + var stat = FileSystem.stat (sourcePath); + + if (stat.size >= maxSize) { + + Sys.println ("Warning: Cannot embed large file \"" + sourcePath + "\" (>16MB)"); + ignoreAsset = true; + + } else { + + /*if (currentSize + stat.size >= maxSize) { + + //compileSWC (project, embed, id); + compileSWC (project, assets, id); + + id++; + currentSize = 0; + embed = ""; + assets = []; + + }*/ + + currentSize += stat.size; + + } + + } catch (e:Dynamic) { + + Sys.println ("Warning: Could not access \"" + sourcePath + "\", does the file exist?"); + ignoreAsset = true; + + } + + if (ignoreAsset) { + + embed += "@:keep class __ASSET__" + asset.flatName + " extends " + flashClass + " { }\n"; + + } else { + + assets.push (asset); + + if (asset.type == IMAGE) { + + embed += "@:keep " + tagName + "('" + sourcePath + "') class __ASSET__" + asset.flatName + " extends " + flashClass + " { public function new () { super (0, 0, true, 0); } }\n"; + + } else { + + embed += "@:keep " + tagName + "('" + sourcePath + "') class __ASSET__" + asset.flatName + " extends " + flashClass + " { }\n"; + + } + + } + + } + + } + + if (embed != "") { + + //compileSWC (project, embed, id); + compileSWC (project, assets, id, targetDirectory); + + } + + for (tempFile in tempFiles) { + + try { + + FileSystem.deleteFile (tempFile); + + } catch (e:Dynamic) {} + + } + + if (assets.length > 0) { + + project.haxeflags.push ("-cp " + targetDirectory); + project.haxeflags.push ("-swf-lib obj/assets.swf"); + project.haxedefs.set ("flash-use-stage", ""); + + return true; + + } + + return false; + + } + + + public static function getLogLength ():Int { + + try { + + var path = switch (PlatformHelper.hostPlatform) { + + case WINDOWS: PathHelper.escape (Sys.getEnv ("APPDATA") + "/Macromedia/Flash Player/Logs/flashlog.txt"); + case MAC: Sys.getEnv ("HOME") + "/Library/Preferences/Macromedia/Flash Player/Logs/flashlog.txt"; + default: Sys.getEnv ("HOME") + "/.macromedia/Flash_Player/Logs/flashlog.txt"; + + } + + if (FileSystem.exists (path)) { + + return FileSystem.stat (path).size; + + } + + } catch (e:Dynamic) { } + + return 0; + + } + + + private static function nextAssetID () { + + return swfAssetID++; + + } + + + public static function run (project:Project, workingDirectory:String, targetPath:String):Void { + + var player:String = null; + + if (!StringTools.endsWith (targetPath, ".html")) { + + if (project.environment.exists ("SWF_PLAYER")) { + + player = project.environment.get ("SWF_PLAYER"); + + } else { + + player = Sys.getEnv ("FLASH_PLAYER_EXE"); + + } + + } + + ProcessHelper.openFile (workingDirectory, targetPath, player); + + } + + + public static function tailLog (start:Int = 0, clear:Bool = true):Void { + + try { + + var path = switch (PlatformHelper.hostPlatform) { + + case WINDOWS: Sys.getEnv ("APPDATA") + "/Macromedia/Flash Player/Logs/flashlog.txt"; + case MAC: Sys.getEnv ("HOME") + "/Library/Preferences/Macromedia/Flash Player/Logs/flashlog.txt"; + default: Sys.getEnv ("HOME") + "/.macromedia/Flash_Player/Logs/flashlog.txt"; + + } + + var position = start; + + if (FileSystem.exists (path)) { + + if (clear) { + + try { + + File.saveContent (path, ""); + position = 0; + + } catch (e:Dynamic) {} + + } + + while (true) { + + var input = null; + + try { + + input = File.read (path, false); + input.seek (position, FileSeek.SeekBegin); + + if (!input.eof ()) { + + var bytes = input.readAll (); + position = input.tell (); + + if (bytes.length > 0) { + + Sys.print (bytes.getString (0, bytes.length)); + + } + + } + + input.close (); + + } catch (e:Dynamic) { + + if (input != null) { + + input.close (); + + } + + } + + Sys.sleep (0.3); + + } + + } + + } catch (e:Dynamic) {} + + } + + +} diff --git a/src/lime/tools/HTML5Helper.hx b/src/lime/tools/HTML5Helper.hx new file mode 100644 index 000000000..dafdf095c --- /dev/null +++ b/src/lime/tools/HTML5Helper.hx @@ -0,0 +1,270 @@ +package lime.tools; + + +import haxe.io.Path; +import haxe.Timer; +import hxp.Log; +import hxp.PathHelper; +import hxp.PlatformHelper; +import hxp.ProcessHelper; +import lime.tools.Architecture; +import hxp.*; +import lime.tools.Asset; +import hxp.Haxelib; +import lime.tools.Project; +import lime.tools.Platform; +import hxp.Version; +import sys.FileSystem; +import sys.io.File; + +#if neko +import neko.vm.Thread; +#elseif cpp +import cpp.vm.Thread; +#end + + +class HTML5Helper { + + + public static function encodeSourceMappingURL (sourceFile:String) { + + // This is only required for projects with url-unsafe characters built with a Haxe version prior to 4.0.0 + + var filename = Path.withoutDirectory (sourceFile); + + if (filename != StringTools.urlEncode (filename)) { + + var output = ProcessHelper.runProcess ("", "haxe", [ "-version" ], true, true, true, false, true); + var haxeVer:Version = StringTools.trim (output); + + if (haxeVer < ("4.0.0" : Version)) { + + var replaceString = "//# sourceMappingURL=" + filename + ".map"; + var replacement = "//# sourceMappingURL=" + StringTools.urlEncode (filename) + ".map"; + + FileHelper.replaceText (sourceFile, replaceString, replacement); + + } + + } + + } + + + // public static function generateFontData (project:Project, font:Asset):String { + + // var sourcePath = font.sourcePath; + + // if (!FileSystem.exists (FileSystem.fullPath (sourcePath) + ".hash")) { + + // var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), "templates") ].concat (project.templatePaths); + // ProcessHelper.runCommand (Path.directory (sourcePath), "neko", [ PathHelper.findTemplate (templatePaths, "bin/hxswfml.n"), "ttf2hash2", Path.withoutDirectory (sourcePath), FileSystem.fullPath (sourcePath) + ".hash", "-glyphs", font.glyphs ]); + + // } + + // return "-resource " + FileSystem.fullPath (sourcePath) + ".hash@__ASSET__" + font.flatName; + + // } + + + public static function generateWebfonts (project:Project, font:Asset):Void { + + var suffix = switch (PlatformHelper.hostPlatform) { + + case WINDOWS: "-windows.exe"; + case MAC: "-mac"; + case LINUX: "-linux"; + default: return; + + } + + if (suffix == "-linux") { + + if (PlatformHelper.hostArchitecture == X86) { + + suffix += "32"; + + } else { + + suffix += "64"; + + } + + } + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), #if lime "templates" #else "" #end) ].concat (project.templatePaths); + var webify = PathHelper.findTemplate (templatePaths, "bin/webify" + suffix); + if (PlatformHelper.hostPlatform != WINDOWS) { + + Sys.command ("chmod", [ "+x", webify ]); + + } + + if (Log.verbose) { + + ProcessHelper.runCommand ("", webify, [ FileSystem.fullPath (font.sourcePath) ]); + + } else { + + ProcessHelper.runProcess ("", webify, [ FileSystem.fullPath (font.sourcePath) ], true, true, true); + + } + + } + + + public static function launch (project:Project, path:String, port:Int = 3000):Void { + + if (project.app.url != null && project.app.url != "") { + + ProcessHelper.openURL (project.app.url); + + } else { + + var suffix = switch (PlatformHelper.hostPlatform) { + + case WINDOWS: "-windows.exe"; + case MAC: "-mac"; + case LINUX: "-linux"; + default: return; + + } + + if (suffix == "-linux") { + + if (PlatformHelper.hostArchitecture == X86) { + + suffix += "32"; + + } else { + + suffix += "64"; + + } + + } + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), #if lime "templates" #else "" #end) ].concat (project.templatePaths); + var node = PathHelper.findTemplate (templatePaths, "bin/node/node" + suffix); + var server = PathHelper.findTemplate (templatePaths, "bin/node/http-server/bin/http-server"); + + if (PlatformHelper.hostPlatform != WINDOWS) { + + Sys.command ("chmod", [ "+x", node ]); + + } + + if (project.targetFlags.exists ("port")) { + + port = Std.parseInt (project.targetFlags.get ("port")); + + } + + Log.info ("", " - \x1b[1mStarting local web server:\x1b[0m http://localhost:" + port); + + /*Thread.create (function () { + + Sys.sleep (0.5); + ProcessHelper.openURL ("http://localhost:" + port); + + });*/ + + var args = [ server, path, "-p", Std.string (port), "-c-1", "--cors" ]; + + if (project.targetFlags.exists ("nolaunch")) { + + Log.info ("\x1b[1mStarting local web server:\x1b[0m http://localhost:" + port); + + } else { + + args.push ("-o"); + + } + + if (!Log.verbose) { + + args.push ("--silent"); + + } + + ProcessHelper.runCommand ("", node, args); + + } + + } + + + public static function minify (project:Project, sourceFile:String):Bool { + + if (FileSystem.exists (sourceFile)) { + + var tempFile = PathHelper.getTemporaryFile (".js"); + + if (project.targetFlags.exists ("yui")) { + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), #if lime "templates" #else "" #end) ].concat (project.templatePaths); + ProcessHelper.runCommand ("", "java", [ "-Dapple.awt.UIElement=true", "-jar", PathHelper.findTemplate (templatePaths, "bin/yuicompressor-2.4.7.jar"), "-o", tempFile, sourceFile ]); + + } else { + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), #if lime "templates" #else "" #end) ].concat (project.templatePaths); + var args = [ "-Dapple.awt.UIElement=true", "-jar", PathHelper.findTemplate (templatePaths, "bin/compiler.jar"), "--strict_mode_input", "false", "--js", sourceFile, "--js_output_file", tempFile ]; + + if (project.targetFlags.exists ("advanced")) { + + args.push ("--compilation_level"); + args.push ("ADVANCED_OPTIMIZATIONS"); + + } + + if (FileSystem.exists (sourceFile + ".map") || project.targetFlags.exists ("source-map")) { + + // if an input .js.map exists closure automatically detects it (from sourceMappingURL) + // --source_map_location_mapping adds file:// to paths (similarly to haxe's .js.map) + + args.push ("--create_source_map"); + args.push (tempFile + ".map"); + args.push ("--source_map_location_mapping"); + args.push ("/|file:///"); + + } + + if (!Log.verbose) { + + args.push ("--jscomp_off=uselessCode"); + + } + + ProcessHelper.runCommand ("", "java", args); + + if (FileSystem.exists (tempFile + ".map")) { + + // closure does not include a sourceMappingURL in the created .js, we do it here + #if !nodejs + var f = File.append (tempFile); + f.writeString ("//# sourceMappingURL=" + StringTools.urlEncode (Path.withoutDirectory (sourceFile)) + ".map"); + f.close (); + #end + + File.copy (tempFile + ".map", sourceFile + ".map"); + FileSystem.deleteFile (tempFile + ".map"); + + } + + } + + FileSystem.deleteFile (sourceFile); + File.copy (tempFile, sourceFile); + FileSystem.deleteFile (tempFile); + + return true; + + } + + return false; + + } + + +} diff --git a/src/lime/tools/HXProject.hx b/src/lime/tools/HXProject.hx new file mode 100644 index 000000000..993a93e45 --- /dev/null +++ b/src/lime/tools/HXProject.hx @@ -0,0 +1,1582 @@ +package lime.tools; + + +import haxe.io.Eof; +import haxe.io.Path; +import haxe.xml.Fast; +import haxe.Json; +import haxe.Serializer; +import haxe.Unserializer; +import hxp.ArrayHelper; +import hxp.FileHelper; +import hxp.HaxelibHelper; +import hxp.Log; +import hxp.ObjectHelper; +import hxp.PathHelper; +import hxp.PlatformHelper; +import hxp.ProcessHelper; +import hxp.StringHelper; +import hxp.StringMapHelper; +import lime.tools.AssetType; +import sys.FileSystem; +import sys.io.File; +import sys.io.Process; + +#if (lime && lime_cffi && !macro) +import lime.text.Font; +@:access(lime.text.Font) +#end + + +class Project { + + + public var app:ApplicationData; + public var architectures:Array; + public var assets:Array; + public var command:String; + public var config:ConfigData; + public var debug:Bool; + public var defines:Map; + public var dependencies:Array; + public var environment:Map; + public var haxedefs:Map; + public var haxeflags:Array; + public var haxelibs:Array; + public var host (get_host, null):Platform; + public var icons:Array; + public var javaPaths:Array; + public var keystore:Keystore; + public var languages:Array; + public var libraries:Array; + public var libraryHandlers:Map; + public var meta:MetaData; + public var modules:Map; + public var ndlls:Array; + public var platformType:PlatformType; + public var postBuildCallbacks:Array; + public var preBuildCallbacks:Array; + public var samplePaths:Array; + public var sources:Array; + public var splashScreens:Array; + public var target:Platform; + public var targetFlags:Map; + public var targetHandlers:Map; + public var templateContext (get_templateContext, null):Dynamic; + public var templatePaths:Array; + @:isVar public var window (get, set):WindowData; + public var windows:Array; + + private var defaultApp:ApplicationData; + private var defaultArchitectures:Array; + private var defaultMeta:MetaData; + private var defaultWindow:WindowData; + private var needRerun:Bool; + + public static var _command:String; + public static var _debug:Bool; + public static var _environment:Map; + public static var _target:Platform; + public static var _targetFlags:Map; + public static var _templatePaths:Array; + public static var _userDefines:Map; + + private static var initialized:Bool; + + + public static function main () { + + var args = Sys.args (); + + if (args.length < 2) { + + return; + + } + + var inputData = Unserializer.run (File.getContent (args[0])); + var outputFile = args[1]; + + Project._command = inputData.command; + Project._target = cast inputData.target; + Project._debug = inputData.debug; + Project._targetFlags = inputData.targetFlags; + Project._templatePaths = inputData.templatePaths; + Project._userDefines = inputData.userDefines; + Project._environment = inputData.environment; + Log.verbose = inputData.logVerbose; + Log.enableColor = inputData.logEnableColor; + + #if lime + ProcessHelper.dryRun = inputData.processDryRun; + #end + + HaxelibHelper.debug = inputData.haxelibDebug; + + initialize (); + + var classRef = Type.resolveClass (inputData.name); + var instance = Type.createInstance (classRef, []); + + var serializer = new Serializer (); + serializer.useCache = true; + serializer.serialize (instance); + + File.saveContent (outputFile, serializer.toString ()); + + } + + + public function new () { + + initialize (); + + command = _command; + config = new ConfigData (); + debug = _debug; + target = _target; + targetFlags = StringMapHelper.copy (_targetFlags); + templatePaths = _templatePaths.copy (); + + defaultMeta = { title: "MyApplication", description: "", packageName: "com.example.myapp", version: "1.0.0", company: "", companyUrl: "", buildNumber: null, companyId: "" } + defaultApp = { main: "Main", file: "MyApplication", path: "bin", preloader: "", swfVersion: 17, url: "", init: null } + defaultWindow = { width: 800, height: 600, parameters: "{}", background: 0xFFFFFF, fps: 30, hardware: true, display: 0, resizable: true, borderless: false, orientation: Orientation.AUTO, vsync: false, fullscreen: false, allowHighDPI: true, alwaysOnTop: false, antialiasing: 0, allowShaders: true, requireShaders: false, depthBuffer: true, stencilBuffer: true, colorDepth: 32, maximized: false, minimized: false, hidden: false } + + platformType = PlatformType.DESKTOP; + architectures = []; + + switch (target) { + + case AIR: + + if (targetFlags.exists ("ios") || targetFlags.exists ("android")) { + + platformType = PlatformType.MOBILE; + + defaultWindow.width = 0; + defaultWindow.height = 0; + + } else { + + platformType = PlatformType.DESKTOP; + + } + + architectures = []; + + case FLASH: + + platformType = PlatformType.WEB; + architectures = []; + + case HTML5, FIREFOX: + + platformType = PlatformType.WEB; + architectures = []; + + defaultWindow.width = 0; + defaultWindow.height = 0; + defaultWindow.fps = 60; + defaultWindow.allowHighDPI = false; + + case EMSCRIPTEN: + + platformType = PlatformType.WEB; + architectures = []; + + defaultWindow.fps = 60; + defaultWindow.allowHighDPI = false; + + case ANDROID, BLACKBERRY, IOS, TIZEN, WEBOS, TVOS: + + platformType = PlatformType.MOBILE; + + if (target == Platform.IOS) { + + architectures = [ Architecture.ARMV7, Architecture.ARM64 ]; + + } else if (target == Platform.ANDROID) { + + if (targetFlags.exists ("simulator") || targetFlags.exists ("emulator")) { + + architectures = [ Architecture.X86 ]; + + } else { + + architectures = [ Architecture.ARMV7 ]; + + } + + } else if (target == Platform.TVOS) { + + architectures = [ Architecture.ARM64 ]; + + } else { + + architectures = [ Architecture.ARMV6 ]; + + } + + defaultWindow.width = 0; + defaultWindow.height = 0; + defaultWindow.fullscreen = true; + defaultWindow.requireShaders = true; + + case WINDOWS: + + platformType = PlatformType.DESKTOP; + + if (targetFlags.exists ("uwp") || targetFlags.exists ("winjs")) { + + architectures = []; + + targetFlags.set ("uwp", ""); + targetFlags.set ("winjs", ""); + + defaultWindow.width = 0; + defaultWindow.height = 0; + defaultWindow.fps = 60; + + } else { + + architectures = [ PlatformHelper.hostArchitecture ]; + + } + + defaultWindow.allowHighDPI = false; + + case MAC, LINUX: + + platformType = PlatformType.DESKTOP; + architectures = [ PlatformHelper.hostArchitecture ]; + + defaultWindow.allowHighDPI = false; + + default: + + // TODO: Better handling of platform type for pluggable targets + + platformType = PlatformType.CONSOLE; + + defaultWindow.width = 0; + defaultWindow.height = 0; + defaultWindow.fps = 60; + defaultWindow.fullscreen = true; + + } + + defaultArchitectures = architectures.copy (); + + meta = ObjectHelper.copyFields (defaultMeta, {}); + app = ObjectHelper.copyFields (defaultApp, {}); + window = ObjectHelper.copyFields (defaultWindow, {}); + windows = [ window ]; + assets = new Array (); + + if (_userDefines != null) { + + defines = StringMapHelper.copy (_userDefines); + + } else { + + defines = new Map (); + + } + + dependencies = new Array (); + + if (_environment != null) { + + environment = _environment; + + } else { + + environment = Sys.environment (); + + } + + haxedefs = new Map (); + haxeflags = new Array (); + haxelibs = new Array (); + icons = new Array (); + javaPaths = new Array (); + languages = new Array (); + libraries = new Array (); + libraryHandlers = new Map (); + modules = new Map (); + ndlls = new Array (); + postBuildCallbacks = new Array (); + preBuildCallbacks = new Array (); + sources = new Array (); + samplePaths = new Array (); + splashScreens = new Array (); + targetHandlers = new Map (); + + } + + + public function clone ():Project { + + var project = new Project (); + + ObjectHelper.copyFields (app, project.app); + project.architectures = architectures.copy (); + project.assets = assets.copy (); + + for (i in 0...assets.length) { + + project.assets[i] = assets[i].clone (); + + } + + project.command = command; + project.config = config.clone (); + project.debug = debug; + + for (key in defines.keys ()) { + + project.defines.set (key, defines.get (key)); + + } + + for (dependency in dependencies) { + + project.dependencies.push (dependency.clone ()); + + } + + for (key in environment.keys ()) { + + project.environment.set (key, environment.get (key)); + + } + + for (key in haxedefs.keys ()) { + + project.haxedefs.set (key, haxedefs.get (key)); + + } + + project.haxeflags = haxeflags.copy (); + + for (haxelib in haxelibs) { + + project.haxelibs.push (haxelib.clone ()); + + } + + for (icon in icons) { + + project.icons.push (icon.clone ()); + + } + + project.javaPaths = javaPaths.copy (); + + if (keystore != null) { + + project.keystore = keystore.clone (); + + } + + project.languages = languages.copy (); + + for (library in libraries) { + + project.libraries.push (library.clone ()); + + } + + for (key in libraryHandlers.keys ()) { + + project.libraryHandlers.set (key, libraryHandlers.get (key)); + + } + + ObjectHelper.copyFields (meta, project.meta); + + for (key in modules.keys ()) { + + project.modules.set (key, modules.get (key).clone ()); + + } + + for (ndll in ndlls) { + + project.ndlls.push (ndll.clone ()); + + } + + project.platformType = platformType; + project.postBuildCallbacks = postBuildCallbacks.copy (); + project.preBuildCallbacks = preBuildCallbacks.copy (); + project.samplePaths = samplePaths.copy (); + project.sources = sources.copy (); + + for (splashScreen in splashScreens) { + + project.splashScreens.push (splashScreen.clone ()); + + } + + project.target = target; + + for (key in targetFlags.keys ()) { + + project.targetFlags.set (key, targetFlags.get (key)); + + } + + for (key in targetHandlers.keys ()) { + + project.targetHandlers.set (key, targetHandlers.get (key)); + + } + + project.templatePaths = templatePaths.copy (); + + for (i in 0...windows.length) { + + project.windows[i] = (ObjectHelper.copyFields (windows[i], {})); + + } + + return project; + + } + + + private function filter (text:String, include:Array = null, exclude:Array = null):Bool { + + if (include == null) { + + include = [ "*" ]; + + } + + if (exclude == null) { + + exclude = []; + + } + + for (filter in exclude) { + + if (filter != "") { + + filter = StringTools.replace (filter, ".", "\\."); + filter = StringTools.replace (filter, "*", ".*"); + + var regexp = new EReg ("^" + filter + "$", "i"); + + if (regexp.match (text)) { + + return false; + + } + + } + + } + + for (filter in include) { + + if (filter != "") { + + filter = StringTools.replace (filter, ".", "\\."); + filter = StringTools.replace (filter, "*", ".*"); + + var regexp = new EReg ("^" + filter, "i"); + + if (regexp.match (text)) { + + return true; + + } + + } + + } + + return false; + + } + + + public static function fromFile (projectFile:String, userDefines:Map = null, includePaths:Array = null):Project { + + var project:Project = null; + + var path = FileSystem.fullPath (Path.withoutDirectory (projectFile)); + var name = Path.withoutDirectory (Path.withoutExtension (projectFile)); + name = name.substr (0, 1).toUpperCase () + name.substr (1); + + var tempDirectory = PathHelper.getTemporaryDirectory (); + var classFile = PathHelper.combine (tempDirectory, name + ".hx"); + var nekoOutput = PathHelper.combine (tempDirectory, name + ".n"); + + FileHelper.copyFile (path, classFile); + + #if lime + var args = [ name, "-main", "lime.tools.Project", "-cp", tempDirectory, "-neko", nekoOutput, "-cp", PathHelper.combine (PathHelper.getHaxelib (new Haxelib ("hxp")), "src"), "-lib", "hxp" ]; + #else + var args = [ name, "--interp", "-main", "lime.tools.Project", "-cp", tempDirectory, "-cp", PathHelper.combine (PathHelper.getHaxelib (new Haxelib ("hxp")), "src") ]; + #end + var input = File.read (classFile, false); + var tag = "@:compiler("; + + try { + + while (true) { + + var line = input.readLine (); + + if (StringTools.startsWith (line, tag)) { + + args.push (line.substring (tag.length + 1, line.length - 2)); + + } + + } + + } catch (ex:Eof) {} + + input.close (); + + var cacheDryRun = ProcessHelper.dryRun; + ProcessHelper.dryRun = false; + + #if lime + ProcessHelper.runCommand ("", "haxe", args); + #end + + var inputFile = PathHelper.combine (tempDirectory, "input.dat"); + var outputFile = PathHelper.combine (tempDirectory, "output.dat"); + + var inputData = Serializer.run ({ + + command: Project._command, + name: name, + target: Project._target, + debug: Project._debug, + targetFlags: Project._targetFlags, + templatePaths: Project._templatePaths, + userDefines: Project._userDefines, + environment: Project._environment, + logVerbose: Log.verbose, + logEnableColor: Log.enableColor, + processDryRun: cacheDryRun, + haxelibDebug: HaxelibHelper.debug + + }); + + File.saveContent (inputFile, inputData); + + try { + + #if lime + ProcessHelper.runCommand ("", "neko", [ FileSystem.fullPath (nekoOutput), inputFile, outputFile ]); + #else + ProcessHelper.runCommand ("", "haxe", args.concat ([ "--", inputFile, outputFile ])); + #end + + } catch (e:Dynamic) { + + FileSystem.deleteFile (inputFile); + Sys.exit (1); + + } + + ProcessHelper.dryRun = cacheDryRun; + + var tPaths:Array = []; + + try { + + FileSystem.deleteFile (inputFile); + + var outputPath = PathHelper.combine (tempDirectory, "output.dat"); + + if (FileSystem.exists (outputPath)) { + + var output = File.getContent (outputPath); + var unserializer = new Unserializer (output); + unserializer.setResolver (cast { resolveEnum: Type.resolveEnum, resolveClass: resolveClass }); + project = unserializer.unserialize (); + + //Because the project file template paths need to take priority, + //Add them after loading template paths from haxelibs below + tPaths = project.templatePaths; + project.templatePaths = []; + + FileSystem.deleteFile (outputPath); + + } + + } catch (e:Dynamic) {} + + PathHelper.removeDirectory (tempDirectory); + + if (project != null) { + + for (key in project.environment.keys ()) { + + Sys.putEnv (key, project.environment[key]); + + } + + var defines = StringMapHelper.copy (userDefines); + StringMapHelper.copyKeys (project.defines, defines); + + processHaxelibs (project, defines); + + //Adding template paths from the Project file + project.templatePaths = ArrayHelper.concatUnique (project.templatePaths, tPaths, true); + } + + return project; + + } + + + public static function fromHaxelib (haxelib:Haxelib, userDefines:Map = null, clearCache:Bool = false):Project { + + if (haxelib.name == null || haxelib.name == "") { + + return null; + + } + + var path = PathHelper.getHaxelib (haxelib, false, clearCache); + + if (path == null || path == "") { + + return null; + + } + + //if (!userDefines.exists (haxelib.name)) { + // + //userDefines.set (haxelib.name, HaxelibHelper.getVersion (haxelib)); + // + //} + + return Project.fromPath (path, userDefines); + + } + + + public static function fromPath (path:String, userDefines:Map = null):Project { + + if (!FileSystem.exists (path) || !FileSystem.isDirectory (path)) { + + return null; + + } + + var files = [ "include.lime", "include.nmml", "include.xml" ]; + var projectFile = null; + + for (file in files) { + + if (projectFile == null && FileSystem.exists (PathHelper.combine (path, file))) { + + projectFile = PathHelper.combine (path, file); + + } + + } + + if (projectFile != null) { + + var project = new ProjectXMLParser (projectFile, userDefines); + + if (project.config.get ("project.rebuild.path") == null) { + + project.config.set ("project.rebuild.path", PathHelper.combine (path, "project")); + + } + + return project; + + } + + return null; + + } + + + private function getHaxelibVersion (haxelib:Haxelib):String { + + var version = haxelib.version; + + if (version == "" || version == null) { + + var haxelibPath = PathHelper.getHaxelib (haxelib); + var jsonPath = PathHelper.combine (haxelibPath, "haxelib.json"); + + try { + + if (FileSystem.exists (jsonPath)) { + + var json = Json.parse (File.getContent (jsonPath)); + version = json.version; + + } + + } catch (e:Dynamic) {} + + } + + return version; + + } + + + public function include (path:String):Void { + + // extend project file somehow? + + } + + + public function includeAssets (path:String, rename:String = null, include:Array = null, exclude:Array = null):Void { + + if (include == null) { + + include = [ "*" ]; + + } + + if (exclude == null) { + + exclude = []; + + } + + exclude = exclude.concat ([ ".*", "cvs", "thumbs.db", "desktop.ini", "*.hash" ]); + + if (path == "") { + + return; + + } + + var targetPath = ""; + + if (rename != null) { + + targetPath = rename; + + } else { + + targetPath = path; + + } + + if (!FileSystem.exists (path)) { + + Log.error ("Could not find asset path \"" + path + "\""); + return; + + } + + var files = FileSystem.readDirectory (path); + + if (targetPath != "") { + + targetPath += "/"; + + } + + for (file in files) { + + if (FileSystem.isDirectory (path + "/" + file)) { + + if (filter (file, [ "*" ], exclude)) { + + includeAssets (path + "/" + file, targetPath + file, include, exclude); + + } + + } else { + + if (filter (file, include, exclude)) { + + assets.push (new Asset (path + "/" + file, targetPath + file)); + + } + + } + + } + + } + + + // #if lime + + public function includeXML (xml:String):Void { + + var projectXML = new ProjectXMLParser (); + @:privateAccess projectXML.parseXML (new Fast (Xml.parse (xml).firstElement ()), ""); + merge (projectXML); + + } + + // #end + + + private static function initialize ():Void { + + if (!initialized) { + + if (_target == null) { + + _target = PlatformHelper.hostPlatform; + + } + + if (_targetFlags == null) { + + _targetFlags = new Map (); + + } + + if (_templatePaths == null) { + + _templatePaths = new Array (); + + } + + initialized = true; + + } + + } + + + public function merge (project:Project):Void { + + if (project != null) { + + ObjectHelper.copyUniqueFields (project.meta, meta, project.defaultMeta); + ObjectHelper.copyUniqueFields (project.app, app, project.defaultApp); + + for (i in 0...project.windows.length) { + + if (i < windows.length) { + + ObjectHelper.copyUniqueFields (project.windows[i], windows[i], project.defaultWindow); + + } else { + + windows.push (ObjectHelper.copyFields (project.windows[i], {})); + + } + + } + + StringMapHelper.copyUniqueKeys (project.defines, defines); + StringMapHelper.copyUniqueKeys (project.environment, environment); + StringMapHelper.copyUniqueKeys (project.haxedefs, haxedefs); + StringMapHelper.copyUniqueKeys (project.libraryHandlers, libraryHandlers); + StringMapHelper.copyUniqueKeys (project.targetHandlers, targetHandlers); + + config.merge (project.config); + + for (architecture in project.architectures) { + + if (defaultArchitectures.indexOf (architecture) == -1) { + + architectures.push (architecture); + + } + + } + + if (project.architectures.length > 0) { + + for (architecture in defaultArchitectures) { + + if (project.architectures.indexOf (architecture) == -1) { + + architectures.remove (architecture); + + } + + } + + } + + assets = ArrayHelper.concatUnique (assets, project.assets); + dependencies = ArrayHelper.concatUnique (dependencies, project.dependencies, true); + haxeflags = ArrayHelper.concatUnique (haxeflags, project.haxeflags); + haxelibs = ArrayHelper.concatUnique (haxelibs, project.haxelibs, true, "name"); + icons = ArrayHelper.concatUnique (icons, project.icons); + javaPaths = ArrayHelper.concatUnique (javaPaths, project.javaPaths, true); + + if (keystore == null) { + + keystore = project.keystore; + + } else { + + keystore.merge (project.keystore); + + } + + languages = ArrayHelper.concatUnique (languages, project.languages, true); + libraries = ArrayHelper.concatUnique (libraries, project.libraries, true); + + for (key in project.modules.keys ()) { + + if (modules.exists (key)) { + + modules.get (key).merge (project.modules.get (key)); + + } else { + + modules.set (key, project.modules.get (key)); + + } + + } + + ndlls = ArrayHelper.concatUnique (ndlls, project.ndlls); + postBuildCallbacks = postBuildCallbacks.concat (project.postBuildCallbacks); + preBuildCallbacks = preBuildCallbacks.concat (project.preBuildCallbacks); + samplePaths = ArrayHelper.concatUnique (samplePaths, project.samplePaths, true); + sources = ArrayHelper.concatUnique (sources, project.sources, true); + splashScreens = ArrayHelper.concatUnique (splashScreens, project.splashScreens); + templatePaths = ArrayHelper.concatUnique (templatePaths, project.templatePaths, true); + + } + + } + + + public function path (value:String):Void { + + if (host == Platform.WINDOWS) { + + setenv ("PATH", value + ";" + Sys.getEnv ("PATH")); + + } else { + + setenv ("PATH", value + ":" + Sys.getEnv ("PATH")); + + } + + } + + + // #if lime + + @:noCompletion private static function processHaxelibs (project:Project, userDefines:Map):Void { + + var haxelibs = project.haxelibs.copy (); + project.haxelibs = []; + + for (haxelib in haxelibs) { + + var validatePath = PathHelper.getHaxelib (haxelib, true); + project.haxelibs.push (haxelib); + + var includeProject = Project.fromHaxelib (haxelib, userDefines); + + if (includeProject != null) { + + for (ndll in includeProject.ndlls) { + + if (ndll.haxelib == null) { + + ndll.haxelib = haxelib; + + } + + } + + project.merge (includeProject); + + } + + } + + } + + + @:noCompletion private static function resolveClass (name:String):Class { + + var type = Type.resolveClass (name); + + if (type == null) { + + return Project; + + } else { + + return type; + + } + + } + + // #end + + + public function setenv (name:String, value:String):Void { + + if (value == null) { + + environment.remove (name); + value = ""; + + } + + if (name == "HAXELIB_PATH") { + + var currentPath = HaxelibHelper.getRepositoryPath (); + Sys.putEnv (name, value); + var newPath = HaxelibHelper.getRepositoryPath (true); + + if (currentPath != newPath) { + + var valid = try { (newPath != null && newPath != "" && FileSystem.exists (FileSystem.fullPath (newPath))); } catch (e:Dynamic) { false; } + + if (!valid) { + + Log.error ("The specified haxelib repository path \"" + value + "\" does not exist"); + + } else { + + needRerun = true; + + } + + } + + } else { + + Sys.putEnv (name, value); + + } + + if (value != "") { + + environment.set (name, value); + + } + + } + + + + + // Getters & Setters + + + + + private function get_host ():Platform { + + return PlatformHelper.hostPlatform; + + } + + + private function get_templateContext ():Dynamic { + + var context:Dynamic = {}; + + if (app == null) app = { }; + if (meta == null) meta = { }; + + if (window == null) { + + window = { }; + windows = [ window ]; + + } + + ObjectHelper.copyMissingFields (defaultApp, app); + ObjectHelper.copyMissingFields (defaultMeta, meta); + + for (item in windows) { + + ObjectHelper.copyMissingFields (defaultWindow, item); + + } + + //config.populate (); + + for (field in Reflect.fields (app)) { + + Reflect.setField (context, "APP_" + StringHelper.formatUppercaseVariable (field), Reflect.field (app, field)); + + } + + context.BUILD_DIR = app.path; + + for (key in environment.keys ()) { + + Reflect.setField (context, "ENV_" + key, environment.get (key)); + + } + + context.meta = meta; + + for (field in Reflect.fields (meta)) { + + Reflect.setField (context, "APP_" + StringHelper.formatUppercaseVariable (field), Reflect.field (meta, field)); + Reflect.setField (context, "META_" + StringHelper.formatUppercaseVariable (field), Reflect.field (meta, field)); + + } + + context.APP_PACKAGE = context.META_PACKAGE = meta.packageName; + + for (field in Reflect.fields (windows[0])) { + + Reflect.setField (context, "WIN_" + StringHelper.formatUppercaseVariable (field), Reflect.field (windows[0], field)); + Reflect.setField (context, "WINDOW_" + StringHelper.formatUppercaseVariable (field), Reflect.field (windows[0], field)); + + } + + if (windows[0].orientation == Orientation.LANDSCAPE || windows[0].orientation == Orientation.PORTRAIT) { + + context.WIN_ORIENTATION = Std.string (windows[0].orientation).toLowerCase (); + context.WINDOW_ORIENTATION = Std.string (windows[0].orientation).toLowerCase (); + + } else { + + context.WIN_ORIENTATION = ""; + context.WINDOW_ORIENTATION = ""; + + } + + context.windows = windows; + + for (i in 0...windows.length) { + + for (field in Reflect.fields (windows[i])) { + + Reflect.setField (context, "WINDOW_" + StringHelper.formatUppercaseVariable (field) + "_" + i, Reflect.field (windows[i], field)); + + } + + if (windows[i].orientation == Orientation.LANDSCAPE || windows[i].orientation == Orientation.PORTRAIT) { + + Reflect.setField (context, "WINDOW_ORIENTATION_" + i, Std.string (windows[i].orientation).toLowerCase ()); + + } else { + + Reflect.setField (context, "WINDOW_ORIENTATION_" + i, ""); + + } + + windows[i].title = meta.title; + + } + + for (haxeflag in haxeflags) { + + if (StringTools.startsWith (haxeflag, "-lib")) { + + Reflect.setField (context, "LIB_" + StringHelper.formatUppercaseVariable (haxeflag.substr (5)), "true"); + + } + + } + + context.assets = new Array (); + + for (asset in assets) { + + if (asset.type != AssetType.TEMPLATE) { + + var embeddedAsset:Dynamic = { }; + ObjectHelper.copyFields (asset, embeddedAsset); + + embeddedAsset.sourcePath = PathHelper.standardize (asset.sourcePath); + + if (asset.embed == null) { + + embeddedAsset.embed = (platformType == PlatformType.WEB || target == AIR); + + } + + embeddedAsset.type = Std.string (asset.type).toLowerCase (); + + #if (lime && lime_cffi && !macro) + if (asset.type == FONT) { + + try { + + var font = Font.fromFile (asset.sourcePath); + embeddedAsset.fontName = font.name; + + Log.info ("", " - \x1b[1mDetecting font name:\x1b[0m " + asset.sourcePath + " \x1b[3;37m->\x1b[0m \"" + font.name + "\""); + + } catch (e:Dynamic) {} + + } + #end + + context.assets.push (embeddedAsset); + + } + + } + + context.languages = (languages.length > 0) ? languages : null; + context.libraries = new Array (); + var embeddedLibraries = new Map (); + + for (library in libraries) { + + var embeddedLibrary:Dynamic = { }; + ObjectHelper.copyFields (library, embeddedLibrary); + context.libraries.push (embeddedLibrary); + embeddedLibraries[library.name] = embeddedLibrary; + + } + + for (asset in assets) { + + if (asset.library != null && !embeddedLibraries.exists (asset.library)) { + + var embeddedLibrary:Dynamic = { }; + embeddedLibrary.name = asset.library; + context.libraries.push (embeddedLibrary); + embeddedLibraries[asset.library] = embeddedLibrary; + + } + + } + + context.ndlls = new Array (); + + for (ndll in ndlls) { + + var templateNDLL:Dynamic = { }; + ObjectHelper.copyFields (ndll, templateNDLL); + templateNDLL.nameSafe = StringTools.replace (ndll.name, "-", "_"); + context.ndlls.push (templateNDLL); + + } + + //Reflect.setField (context, "ndlls", ndlls); + //Reflect.setField (context, "sslCaCert", sslCaCert); + context.sslCaCert = ""; + + var compilerFlags = []; + + for (haxelib in haxelibs) { + + var name = haxelib.name; + + // TODO: Handle real version when better/smarter haxelib available + var version = haxelib.version; + //var version = HaxelibHelper.getVersion (haxelib); + + if (version != null && version != "") { + + name += ":" + version; + + } + + // #if lime + + if (HaxelibHelper.pathOverrides.exists (name)) { + + var param = "-cp " + HaxelibHelper.pathOverrides.get (name); + compilerFlags.remove (param); + compilerFlags.push (param); + + } else { + + var cache = Log.verbose; + Log.verbose = HaxelibHelper.debug; + var output = ""; + + try { + + output = HaxelibHelper.runProcess ("", [ "path", name ], true, true, true); + + } catch (e:Dynamic) { } + + Log.verbose = cache; + + var split = output.split ("\n"); + var haxelibName = null; + + for (arg in split) { + + arg = StringTools.trim (arg); + + if (arg != "") { + + if (StringTools.startsWith (arg, "Error: ")) { + + Log.error (arg.substr (7)); + + } else if (!StringTools.startsWith (arg, "-")) { + + var path = PathHelper.standardize (arg); + + if (path != null && StringTools.trim (path) != "" && !StringTools.startsWith (StringTools.trim (path), "#")) { + + var param = "-cp " + path; + compilerFlags.remove (param); + compilerFlags.push (param); + + } + + var version = "0.0.0"; + var jsonPath = PathHelper.combine (path, "haxelib.json"); + + try { + + if (FileSystem.exists (jsonPath)) { + + var json = Json.parse (File.getContent (jsonPath)); + haxelibName = json.name; + compilerFlags = ArrayHelper.concatUnique (compilerFlags, [ "-D " + haxelibName + "=" + json.version ], true); + + } + + } catch (e:Dynamic) {} + + } else { + + if (StringTools.startsWith (arg, "-D ") && arg.indexOf ("=") == -1) { + + var name = arg.substr (3); + + if (name != haxelibName) { + + compilerFlags = ArrayHelper.concatUnique (compilerFlags, [ "-D " + name ], true); + + } + + /*var haxelib = new Haxelib (arg.substr (3)); + var path = PathHelper.getHaxelib (haxelib); + var version = getHaxelibVersion (haxelib); + + if (path != null) { + + CompatibilityHelper.patchProject (this, haxelib, version); + compilerFlags = ArrayHelper.concatUnique (compilerFlags, [ "-D " + haxelib.name + "=" + version ], true); + + }*/ + + } else if (!StringTools.startsWith (arg, "-L")) { + + compilerFlags = ArrayHelper.concatUnique (compilerFlags, [ arg ], true); + + } + + } + + } + + } + + } + + // #else + + // compilerFlags.push ("-lib " + name); + + // #end + + Reflect.setField (context, "LIB_" + StringHelper.formatUppercaseVariable (haxelib.name), true); + + if (name == "nme") { + + context.EMBED_ASSETS = false; + + } + + } + + for (source in sources) { + + if (source != null && StringTools.trim (source) != "") { + + compilerFlags.push ("-cp " + source); + + } + + } + + for (key in defines.keys ()) { + + var value = defines.get (key); + + if (value == null || value == "") { + + Reflect.setField (context, "SET_" + StringHelper.formatUppercaseVariable (key), true); + + } else { + + Reflect.setField (context, "SET_" + StringHelper.formatUppercaseVariable (key), value); + + } + + } + + for (key in haxedefs.keys ()) { + + var value = haxedefs.get (key); + + if (value == null || value == "") { + + compilerFlags.push ("-D " + key); + + Reflect.setField (context, "DEFINE_" + StringHelper.formatUppercaseVariable (key), true); + + } else { + + compilerFlags.push ("-D " + key + "=" + value); + + Reflect.setField (context, "DEFINE_" + StringHelper.formatUppercaseVariable (key), value); + + } + + } + + if (target != Platform.FLASH) { + + compilerFlags.push ("-D " + Std.string (target).toLowerCase ()); + + } + + compilerFlags.push ("-D " + Std.string (platformType).toLowerCase ()); + compilerFlags = compilerFlags.concat (haxeflags); + + if (compilerFlags.length == 0) { + + context.HAXE_FLAGS = ""; + + } else { + + context.HAXE_FLAGS = "\n" + compilerFlags.join ("\n"); + + } + + var main = app.main; + + if (main == null) { + + main = defaultApp.main; + + } + + var indexOfPeriod = main.lastIndexOf ("."); + + context.APP_MAIN_PACKAGE = main.substr (0, indexOfPeriod + 1); + context.APP_MAIN_CLASS = main.substr (indexOfPeriod + 1); + + var type = "release"; + + if (debug) { + + type = "debug"; + + } else if (targetFlags.exists ("final")) { + + type = "final"; + + } + + var hxml = Std.string (target).toLowerCase () + "/hxml/" + type + ".hxml"; + + for (templatePath in templatePaths) { + + var path = PathHelper.combine (templatePath, hxml); + + if (FileSystem.exists (path)) { + + context.HXML_PATH = path; + + } + + } + + context.RELEASE = (type == "release"); + context.DEBUG = debug; + context.FINAL = (type == "final"); + context.SWF_VERSION = app.swfVersion; + context.PRELOADER_NAME = app.preloader; + + if (keystore != null) { + + context.KEY_STORE = PathHelper.tryFullPath (keystore.path); + + if (keystore.password != null) { + + context.KEY_STORE_PASSWORD = keystore.password; + + } + + if (keystore.alias != null) { + + context.KEY_STORE_ALIAS = keystore.alias; + + } else if (keystore.path != null) { + + context.KEY_STORE_ALIAS = Path.withoutExtension (Path.withoutDirectory (keystore.path)); + + } + + if (keystore.aliasPassword != null) { + + context.KEY_STORE_ALIAS_PASSWORD = keystore.aliasPassword; + + } else if (keystore.password != null) { + + context.KEY_STORE_ALIAS_PASSWORD = keystore.password; + + } + + } + + context.config = config; + + return context; + + } + + + private function get_window ():WindowData { + + if (windows != null) { + + return windows[0]; + + } else { + + return window; + + } + + } + + + private function set_window (value:WindowData):WindowData { + + if (windows != null) { + + return windows[0] = window = value; + + } else { + + return window = value; + + } + + } + + +} diff --git a/src/lime/tools/IOSHelper.hx b/src/lime/tools/IOSHelper.hx new file mode 100644 index 000000000..758d632e9 --- /dev/null +++ b/src/lime/tools/IOSHelper.hx @@ -0,0 +1,448 @@ +package lime.tools; + + +import haxe.io.Path; +import lime.tools.Platform; +import hxp.PathHelper; +import hxp.ProcessHelper; +import hxp.Haxelib; +import hxp.*; +import lime.tools.Project; +import sys.io.Process; +import sys.FileSystem; + + +class IOSHelper { + + + private static var initialized = false; + + + public static function build (project:Project, workingDirectory:String, additionalArguments:Array = null):Void { + + initialize (project); + + var commands = getXCodeArgs(project); + + if (project.targetFlags.exists("archive")) { + + var configuration = project.environment.get ("CONFIGURATION"); + var platformName = project.environment.get ("PLATFORM_NAME"); + + commands.push ("archive"); + commands.push ("-scheme"); + commands.push (project.app.file); + commands.push ("-archivePath"); + commands.push (PathHelper.combine ("build", PathHelper.combine (configuration + "-" + platformName, project.app.file))); + + } else { + + commands.push ("build"); + + } + + if (additionalArguments != null) { + + commands = commands.concat (additionalArguments); + + } + + ProcessHelper.runCommand (workingDirectory, "xcodebuild", commands); + + } + + + public static function deploy (project:Project, workingDirectory:String):Void { + + initialize (project); + + var commands = getXCodeArgs (project); + var archiveCommands = commands.concat ([]); + + // generate xcarchive + var configuration = project.environment.get ("CONFIGURATION"); + var platformName = project.environment.get ("PLATFORM_NAME"); + + archiveCommands.push ("archive"); + archiveCommands.push ("-scheme"); + archiveCommands.push (project.app.file); + archiveCommands.push ("-archivePath"); + archiveCommands.push (PathHelper.combine ("build", PathHelper.combine (configuration + "-" + platformName, project.app.file))); + + ProcessHelper.runCommand (workingDirectory, "xcodebuild", archiveCommands); + + var supportedExportMethods = [ "adhoc", "development", "enterprise", "appstore" ]; + var exportMethods = []; + for (m in supportedExportMethods) { + if (project.targetFlags.exists(m)) { + exportMethods.push(m); + } + } + + if (exportMethods.length == 0) { + exportMethods.push("appstore"); + } + + for (exportMethod in exportMethods) { + // generate IPA from xcarchive + var exportCommands = commands.concat ([]); + + exportCommands.push ("-exportArchive"); + exportCommands.push ("-archivePath"); + exportCommands.push (PathHelper.combine ("build", PathHelper.combine (configuration + "-" + platformName, project.app.file + ".xcarchive"))); + exportCommands.push ("-exportOptionsPlist"); + exportCommands.push (PathHelper.combine (project.app.file, "exportOptions-" + exportMethod + ".plist")); + exportCommands.push ("-exportPath"); + exportCommands.push (PathHelper.combine ("dist", exportMethod)); + + ProcessHelper.runCommand (workingDirectory, "xcodebuild", exportCommands); + } + + } + + + private static function getXCodeArgs (project:Project):Array { + + var platformName = "iphoneos"; + var iphoneVersion = project.environment.get ("IPHONE_VER"); + + if (project.targetFlags.exists ("simulator")) { + + platformName = "iphonesimulator"; + + } + + var configuration = "Release"; + + if (project.debug) { + + configuration = "Debug"; + + } + + project.setenv ("PLATFORM_NAME", platformName); + project.setenv ("CONFIGURATION", configuration); + + // setting CONFIGURATION and PLATFORM_NAME in project.environment doesn't set them for xcodebuild so also pass via command line + var commands = [ "-configuration", configuration, "PLATFORM_NAME=" + platformName, "SDKROOT=" + platformName + iphoneVersion ]; + + if (project.targetFlags.exists ("simulator")) { + + if (project.targetFlags.exists ("i386") || project.targetFlags.exists ("32")) { + + commands.push ("-arch"); + commands.push ("i386"); + + } else { + + commands.push ("-arch"); + commands.push ("x86_64"); + + } + + } else if (project.targetFlags.exists ("armv7")) { + + commands.push ("-arch"); + commands.push ("armv7"); + + } else if (project.targetFlags.exists ("armv7s")) { + + commands.push ("-arch"); + commands.push ("armv7s"); + + } else if (project.targetFlags.exists ("arm64")) { + + commands.push ("-arch"); + commands.push ("arm64"); + + } + + commands.push ("-project"); + commands.push (project.app.file + ".xcodeproj"); + + var xcodeVersions = getXcodeVersion() + .split(".") + .map(function (i:String) { + var ver = Std.parseInt(i); + return ver != null ? ver : 0; + }); + + if (xcodeVersions[0] >= 9) { + if (project.config.getBool('ios.allow-provisioning-updates', true)) { + commands.push("-allowProvisioningUpdates"); + } + if (project.config.getBool('ios.allow-provisioning-device-registration', true)) { + commands.push("-allowProvisioningDeviceRegistration"); + } + } + + return commands; + + } + + + public static function getSDKDirectory (project:Project):String { + + initialize (project); + + var platformName = "iPhoneOS"; + + if (project.targetFlags.exists ("simulator")) { + + platformName = "iPhoneSimulator"; + + } + + var process = new Process ("xcode-select", [ "--print-path" ]); + var directory = process.stdout.readLine (); + process.close (); + + if (directory == "" || directory.indexOf ("Run xcode-select") > -1) { + + directory = "/Applications/Xcode.app/Contents/Developer"; + + } + + directory += "/Platforms/" + platformName + ".platform/Developer/SDKs/" + platformName + project.environment.get ("IPHONE_VER") + ".sdk"; + return directory; + + } + + + public static function getIOSVersion (project:Project):Void { + + if (!project.environment.exists ("IPHONE_VER") || project.environment.get ("IPHONE_VER") == "4.2") { + + if (!project.environment.exists ("DEVELOPER_DIR") && PlatformHelper.hostPlatform == MAC) { + + var process = new Process ("xcode-select", [ "--print-path" ]); + var developerDir = process.stdout.readLine (); + process.close (); + + project.environment.set ("DEVELOPER_DIR", developerDir); + + } + + var devPath = project.environment.get ("DEVELOPER_DIR") + "/Platforms/iPhoneOS.platform/Developer/SDKs"; + + if (FileSystem.exists (devPath)) { + + var files = FileSystem.readDirectory (devPath); + var extractVersion = ~/^iPhoneOS(.*).sdk$/; + var best = "0", version; + + for (file in files) { + + if (extractVersion.match (file)) { + + version = extractVersion.matched (1); + + if (Std.parseFloat (version) > Std.parseFloat (best)) { + + best = version; + + } + + } + + } + + if (best != "") { + + project.environment.set ("IPHONE_VER", best); + + } + + } + + } + + } + + + private static function getOSXVersion ():String { + + var output = ProcessHelper.runProcess ("", "sw_vers", [ "-productVersion" ]); + + return StringTools.trim (output); + + } + + + public static function getProvisioningFile (project:Project = null):String { + + if (project != null && project.config.exists ("ios.provisioning-profile")) { + + return PathHelper.tryFullPath (project.config.getString ("ios.provisioning-profile")); + + } else if (PlatformHelper.hostPlatform == MAC) { + + var path = PathHelper.expand ("~/Library/MobileDevice/Provisioning Profiles"); + var files = FileSystem.readDirectory (path); + + for (file in files) { + + if (Path.extension (file) == "mobileprovision") { + + return path + "/" + file; + + } + + } + + } + + return ""; + + } + + + private static function getXcodeVersion ():String { + + var output = ProcessHelper.runProcess ("", "xcodebuild", [ "-version" ]); + var firstLine = output.split ("\n").shift (); + + return StringTools.trim (firstLine.substring ("Xcode".length, firstLine.length)); + + } + + + private static function initialize (project:Project):Void { + + if (!initialized) { + + getIOSVersion (project); + + initialized = true; + + } + + } + + + public static function launch (project:Project, workingDirectory:String):Void { + + initialize (project); + + var configuration = "Release"; + + if (project.debug) { + + configuration = "Debug"; + + } + + if (project.targetFlags.exists ("simulator")) { + + var applicationPath = ""; + + if (Path.extension (workingDirectory) == "app" || Path.extension (workingDirectory) == "ipa") { + + applicationPath = workingDirectory; + + } else { + + applicationPath = workingDirectory + "/build/" + configuration + "-iphonesimulator/" + project.app.file + ".app"; + + } + + var currentDeviceID = XCodeHelper.getSimulatorID (project); + + try { + + ProcessHelper.runProcess ("", "open", [ "-Ra", "iOS Simulator" ], true, false); + ProcessHelper.runCommand ("", "open", [ "-a", "iOS Simulator", "--args", "-CurrentDeviceUDID", currentDeviceID ]); + + } catch (e:Dynamic) { + + ProcessHelper.runCommand ("", "open", [ "-a", "Simulator", "--args", "-CurrentDeviceUDID", currentDeviceID ]); + + } + + waitForDeviceState ("xcrun", [ "simctl", "uninstall", currentDeviceID, project.meta.packageName ]); + waitForDeviceState ("xcrun", [ "simctl", "install", currentDeviceID, applicationPath ]); + waitForDeviceState ("xcrun", [ "simctl", "launch", currentDeviceID, project.meta.packageName ]); + + ProcessHelper.runCommand ("", "tail", [ "-F", "~/Library/Logs/CoreSimulator/" + currentDeviceID + "/system.log"]); + + } else { + + var applicationPath = ""; + + if (Path.extension (workingDirectory) == "app" || Path.extension (workingDirectory) == "ipa") { + + applicationPath = workingDirectory; + + } else { + + applicationPath = workingDirectory + "/build/" + configuration + "-iphoneos/" + project.app.file + ".app"; + + } + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), #if lime "templates" #else "" #end) ].concat (project.templatePaths); + var launcher = PathHelper.findTemplate (templatePaths, "bin/ios-deploy"); + Sys.command ("chmod", [ "+x", launcher ]); + + // var xcodeVersion = getXcodeVersion (); + + ProcessHelper.runCommand ("", launcher, [ "install", "--noninteractive", "--debug", "--bundle", FileSystem.fullPath (applicationPath) ]); + + } + + } + + + public static function sign (project:Project, workingDirectory:String):Void { + + initialize (project); + + var configuration = "Release"; + + if (project.debug) { + + configuration = "Debug"; + + } + + var identity = project.config.getString ("ios.identity", "iPhone Developer"); + + var commands = [ "-s", identity, "CODE_SIGN_IDENTITY=" + identity ]; + + if (project.config.exists ("ios.provisioning-profile")) { + + commands.push ("PROVISIONING_PROFILE=" + project.config.getString ("ios.provisioning-profile")); + + } + + var applicationPath = "build/" + configuration + "-iphoneos/" + project.app.file + ".app"; + commands.push (applicationPath); + + ProcessHelper.runCommand (workingDirectory, "codesign", commands, true, true); + + } + + + private static function waitForDeviceState (command:String, args:Array):Void { + + var output; + + while (true) { + + output = ProcessHelper.runProcess ("", command, args, true, true, true); + + if (output != null && output.toLowerCase ().indexOf ("invalid device state") > -1) { + + Sys.sleep (3); + + } else { + + break; + + } + + } + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/Icon.hx b/src/lime/tools/Icon.hx new file mode 100644 index 000000000..412a92ba7 --- /dev/null +++ b/src/lime/tools/Icon.hx @@ -0,0 +1,33 @@ +package lime.tools; + + +class Icon { + + + public var height:Int; + public var path:String; + public var size:Int; + public var width:Int; + + + public function new (path:String, size:Int = 0) { + + this.path = path; + this.size = height = width = size; + + } + + + public function clone ():Icon { + + var icon = new Icon (path); + icon.size = size; + icon.width = width; + icon.height = height; + + return icon; + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/IconHelper.hx b/src/lime/tools/IconHelper.hx new file mode 100644 index 000000000..48f92c8e3 --- /dev/null +++ b/src/lime/tools/IconHelper.hx @@ -0,0 +1,461 @@ +package lime.tools; + + +//import openfl.display.Bitmap; +//import openfl.display.BitmapData; +//import openfl.display.Shape; +//import openfl.geom.Rectangle; +//import openfl.utils.ByteArray; +//import format.SVG; +import haxe.io.Bytes; +import haxe.io.BytesOutput; +import haxe.io.Path; +import hxp.FileHelper; +import lime.tools.ImageHelper; +import hxp.Log; +import hxp.PathHelper; +#if (lime && lime_cffi && !macro) +import lime.graphics.Image; +import lime.math.Rectangle; +#end +import lime.tools.Icon; +import sys.io.File; +import sys.FileSystem; + + +class IconHelper { + + + private static function canUseCache (targetPath:String, icons:Array):Bool { + + if (FileSystem.exists (targetPath)) { + + var cacheTime = FileHelper.getLastModified (targetPath); + + for (icon in icons) { + + if (FileHelper.getLastModified (icon.path) > cacheTime) { + + return false; + + } + + } + + return true; + + } + + return false; + + } + + + public static function createIcon (icons:Array, width:Int, height:Int, targetPath:String):Bool { + + #if (lime && lime_cffi && !macro) + + var icon = findMatch (icons, width, height); + + if (icon != null && icon.size > 0 && Path.extension (icon.path) == "png") { + + if (canUseCache (targetPath, [ icon ])) { + + return true; + + } + + PathHelper.mkdir (Path.directory (targetPath)); + FileHelper.copyFile (icon.path, targetPath); + return true; + + } else { + + if (canUseCache (targetPath, icons)) { + + return true; + + } + + var image = getIconImage (icons, width, height); + + if (image != null) { + + var bytes = image.encode (PNG); + + if (bytes != null) { + + PathHelper.mkdir (Path.directory (targetPath)); + File.saveBytes (targetPath, bytes); + return true; + + } + + } + + } + + #end + + return false; + + } + + + public static function createMacIcon (icons:Array, targetPath:String):Bool { + + #if (lime && lime_cffi && !macro) + if (canUseCache (targetPath, icons)) { + + return true; + + } + + var out = new BytesOutput (); + out.bigEndian = true; + + // Not sure why the 128x128 icon is not saving properly. Disabling for now + + for (i in 0...3) { + + var s = ([ 16, 32, 48, 128 ])[i]; + var code = ([ "is32", "il32", "ih32", "it32" ])[i]; + var image = getIconImage (icons, s, s); + + if (image != null) { + + for (c in 0...4) out.writeByte (code.charCodeAt(c)); + + var n = s * s; + var pixels = image.getPixels (new Rectangle (0, 0, s, s), ARGB32); + + var bytes_r = packBits (pixels, 1, s * s); + var bytes_g = packBits (pixels, 2, s * s); + var bytes_b = packBits (pixels, 3, s * s); + + out.writeInt32 (bytes_r.length + bytes_g.length + bytes_b.length + 8); + out.writeBytes (bytes_r, 0, bytes_r.length); + out.writeBytes (bytes_g, 0, bytes_g.length); + out.writeBytes (bytes_b, 0, bytes_b.length); + + var code = ([ "s8mk", "l8mk", "h8mk", "t8mk" ])[i]; + + for (c in 0...4) out.writeByte (code.charCodeAt (c)); + + var bytes_a = extractBits (pixels, 0, s * s); + out.writeInt32 (bytes_a.length + 8); + out.writeBytes (bytes_a, 0, bytes_a.length); + + } + + } + + for (i in 0...5) { + + var s = ([ 32, 64, 256, 512, 1024 ])[i]; + var code = ([ "ic11", "ic12", "ic08", "ic09", "ic10" ])[i]; + var image = getIconImage (icons, s, s); + + if (image != null) { + + var bytes = image.encode (PNG); + + if (bytes != null) { + + for (c in 0...4) out.writeByte (code.charCodeAt(c)); + + out.writeInt32 (bytes.length + 8); + out.writeBytes (bytes, 0, bytes.length); + + } + + } + + } + + var bytes = out.getBytes (); + + if (bytes.length > 0) { + + var file = File.write (targetPath, true); + file.bigEndian = true; + + for (c in 0...4) file.writeByte ("icns".charCodeAt (c)); + + file.writeInt32 (bytes.length + 8); + file.writeBytes (bytes, 0, bytes.length); + file.close (); + + return true; + + } + #end + + return false; + + } + + + public static function createWindowsIcon (icons:Array, targetPath:String):Bool { + + #if (lime && lime_cffi && !macro) + if (canUseCache (targetPath, icons)) { + + return true; + + } + + var sizes = [ 16, 24, 32, 40, 48, 64, 96, 128, 256, 512, 768 ]; + + var images = new Array (); + var imageData = new Array (); + + for (size in sizes) { + + var image = getIconImage (icons, size, size); + + if (image != null) { + + var data = null; + + if (size < 256) { + + data = lime._internal.format.BMP.encode (image, ICO); + + } else { + + data = image.encode (PNG); + + } + + if (data != null) { + + imageData.push (data); + images.push (image); + + } + + } + + } + + var length = 6 + (16 * images.length); + + for (data in imageData) { + + length += data.length; + + } + + var icon = Bytes.alloc (length); + var position = 0; + icon.setUInt16 (position, 0); position += 2; + icon.setUInt16 (position, 1); position += 2; + icon.setUInt16 (position, images.length); position += 2; + + var dataOffset = 6 + (16 * images.length); + + for (i in 0...images.length) { + + var size = images[i].width; + + icon.set (position++, size > 255 ? 0 : size); + icon.set (position++, size > 255 ? 0 : size); + icon.set (position++, 0); + icon.set (position++, 0); + icon.setUInt16 (position, 1); position += 2; + icon.setUInt16 (position, 32); position += 2; + icon.setInt32 (position, imageData[i].length); position += 4; + icon.setInt32 (position, dataOffset); position += 4; + + dataOffset += imageData[i].length; + + } + + for (data in imageData) { + + icon.blit (position, data, 0, data.length); + position += data.length; + + } + + if (images.length > 0) { + + File.saveBytes (targetPath, icon); + return true; + + } + #end + + return false; + + } + + + private static function extractBits (data:Bytes, offset:Int, len:Int):Bytes { + + var out = new BytesOutput (); + + for (i in 0...len) { + + out.writeByte (data.get (i * 4 + offset)); + + } + + return out.getBytes (); + + } + + + public static function findMatch (icons:Array, width:Int, height:Int):Icon { + + var match = null; + + for (icon in icons) { + + if ((icon.width == 0 && icon.height == 0) || (icon.width == width && icon.height == height)) { + + match = icon; + + } + + } + + return match; + + } + + + public static function findNearestMatch (icons:Array, width:Int, height:Int):Icon { + + var match = null; + + for (icon in icons) { + + if (icon.width > width / 2 && icon.height > height / 2) { + + if (match == null) { + + match = icon; + + } else { + + if (icon.width > match.width && icon.height > match.height) { + + if (match.width < width || match.height < height) { + + match = icon; + + } + + } else { + + if (icon.width > width && icon.height > height) { + + match = icon; + + } + + } + + } + + } + + } + + return match; + + } + + + private static function getIconImage (icons:Array, width:Int, height:Int, backgroundColor:Int = null):#if (lime && lime_cffi && !macro) Image #else Dynamic #end { + + var icon = findMatch (icons, width, height); + + if (icon == null) { + + icon = findNearestMatch (icons, width, height); + + } + + if (icon == null) { + + return null; + + } + + if (icon.path == null || !FileSystem.exists (icon.path)) { + + Log.warn ("Could not find icon path: " + icon.path); + return null; + + } + + var extension = Path.extension (icon.path); + var image = null; + + #if (lime && lime_cffi && !macro) + switch (extension) { + + case "png", "jpg", "jpeg": + + image = ImageHelper.resizeImage (Image.fromFile (icon.path), width, height); + + case "svg": + + //image = ImageHelper.rasterizeSVG (null /*new SVG (File.getContent (icon.path))*/, width, height, backgroundColor); + image = ImageHelper.rasterizeSVG (icon.path, width, height, backgroundColor); + + } + #end + + return image; + + } + + + private static function packBits (data:Bytes, offset:Int, len:Int):Bytes { + + var out = new BytesOutput (); + var idx = 0; + + while (idx < len) { + + var val = data.get (idx * 4 + offset); + var same = 1; + + /* + Hmmmm... + while( ((idx+same) < len) && (data[ (idx+same)*4 + offset ]==val) && (same < 2) ) + same++; + */ + + if (same == 1) { + + var raw = idx + 120 < len ? 120 : len - idx; + out.writeByte (raw - 1); + + for (i in 0...raw) { + + out.writeByte (data.get (idx * 4 + offset)); + idx++; + + } + + } else { + + out.writeByte (257 - same); + out.writeByte (val); + idx += same; + + } + + } + + return out.getBytes (); + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/ImageHelper.hx b/src/lime/tools/ImageHelper.hx new file mode 100644 index 000000000..83264ae0e --- /dev/null +++ b/src/lime/tools/ImageHelper.hx @@ -0,0 +1,152 @@ +package lime.tools; + + +#if (lime && lime_cffi && !macro) +import lime.graphics.Image; +import lime.graphics.ImageBuffer; +import lime.utils.UInt8Array; +#end +import hxp.PathHelper; +import hxp.Haxelib; +import lime.tools.Platform; +import hxp.*; +import sys.io.File; +import sys.FileSystem; + + +class ImageHelper { + + + public static function rasterizeSVG (path:String, width:Int, height:Int, backgroundColor:Int = null):#if (lime && lime_cffi && !macro) Image #else Dynamic #end { + //public static function rasterizeSVG (svg:Dynamic /*SVG*/, width:Int, height:Int, backgroundColor:Int = null):Image { + + #if (lime && lime_cffi && !macro) + if (path == null) return null; + + var temp = PathHelper.getTemporaryFile (".png"); + + try { + + ProcessHelper.runCommand ("", "neko", [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), "svg.n"), "process", path, Std.string (width), Std.string (height), temp ], true, true); + + if (FileSystem.exists (temp)) { + + var image = Image.fromFile (temp); + + try { + + FileSystem.deleteFile (temp); + + } catch (e:Dynamic) {} + + if (image.buffer != null) { + + return image; + + } + + } + + } catch (e:Dynamic) {} + + var rasterizer = PathHelper.getHaxelib (new Haxelib ("lime")) + "/templates/bin/batik/batik-rasterizer.jar"; + var args = [ "-Dapple.awt.UIElement=true", "-jar", rasterizer, "-d", temp, "-w", Std.string (width), "-h", Std.string (height) ]; + + if (backgroundColor != null) { + + var a:Int = (( backgroundColor >> 24) & 0xFF); + var r:Int = (( backgroundColor >> 16) & 0xFF); + var g:Int = (( backgroundColor >> 8) & 0xFF); + var b:Int = (backgroundColor & 0xFF); + + args.push ("-bg"); + args.push (a + "." + r + "." + g + "." + b); + + } + + args.push (path); + + if (PlatformHelper.hostPlatform == MAC) { + + try { + + var found = false; + + if (FileSystem.exists ("/System/Library/Java/JavaVirtualMachines")) { + + found = (FileSystem.readDirectory ("/System/Library/Java/JavaVirtualMachines").length > 0); + + } + + if (!found && FileSystem.exists ("/Library/Java/JavaVirtualMachines")) { + + found = (FileSystem.readDirectory ("/Library/Java/JavaVirtualMachines").length > 0); + + } + + if (!found) { + + if (Log.verbose) Log.warn ("Skipping SVG to PNG rasterization step, no Java runtime detected"); + + return null; + + } + + } catch (e:Dynamic) {} + + } + + if (Log.verbose) { + + ProcessHelper.runCommand ("", "java", args, true, true); + + } else { + + ProcessHelper.runProcess ("", "java", args, true, true, true); + + } + + if (FileSystem.exists (temp)) { + + var image = Image.fromFile (temp); + + try { + + FileSystem.deleteFile (temp); + + } catch (e:Dynamic) {} + + if (image.buffer != null) { + + return image; + + } + + } + #end + + return null; + + } + + + public static function resizeImage (image:#if (lime && lime_cffi && !macro) Image #else Dynamic #end, width:Int, height:Int):#if (lime && lime_cffi && !macro) Image #else Dynamic #end { + + #if (lime && lime_cffi && !macro) + if (image == null) return null; + + if (image.width == width && image.height == height) { + + return image; + + } + + image.resize (width, height); + #end + + return image; + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/JavaHelper.hx b/src/lime/tools/JavaHelper.hx new file mode 100644 index 000000000..a3420a565 --- /dev/null +++ b/src/lime/tools/JavaHelper.hx @@ -0,0 +1,18 @@ +package lime.tools; + + +import hxp.*; +import sys.io.File; + + +class JavaHelper { + + + public static function copyLibraries (templatePaths:Array, platformName:String, targetPath:String) { + + FileHelper.recursiveCopyTemplate (templatePaths, "java/ndll/" + platformName, targetPath); + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/Keystore.hx b/src/lime/tools/Keystore.hx new file mode 100644 index 000000000..4dbc32a50 --- /dev/null +++ b/src/lime/tools/Keystore.hx @@ -0,0 +1,40 @@ +package lime.tools; + + +class Keystore { + + public var alias:String; + public var aliasPassword:String; + public var password:String; + public var path:String; + public var type:String; + + public function new (path:String = null, password:String = null, alias:String = null, aliasPassword:String = null) { + + this.path = path; + this.password = password; + this.alias = alias; + this.aliasPassword = aliasPassword; + + } + + public function clone ():Keystore { + + return new Keystore (path, password, alias, aliasPassword); + + } + + public function merge (keystore:Keystore):Void { + + if (keystore != null) { + + if (keystore.path != null && keystore.path != "") path = keystore.path; + if (keystore.password != null) path = keystore.password; + if (keystore.alias != null) path = keystore.alias; + if (keystore.aliasPassword != null) path = keystore.aliasPassword; + + } + + } + +} \ No newline at end of file diff --git a/src/lime/tools/Library.hx b/src/lime/tools/Library.hx new file mode 100644 index 000000000..a1cb2b27f --- /dev/null +++ b/src/lime/tools/Library.hx @@ -0,0 +1,49 @@ +package lime.tools; + + +import haxe.io.Path; + + +class Library { + + + public var embed:Null; + public var generate:Bool; + public var name:String; + public var prefix:String; + public var preload:Bool; + public var sourcePath:String; + public var type:String; + + + public function new (sourcePath:String, name:String = "", type:String = null, embed:Null = null, preload:Bool = false, generate:Bool = false, prefix:String = "") { + + this.sourcePath = sourcePath; + + if (name == "") { + + this.name = Path.withoutDirectory (Path.withoutExtension (sourcePath)); + + } else { + + this.name = name; + + } + + this.type = type; + this.embed = embed; + this.preload = preload; + this.generate = generate; + this.prefix = prefix; + + } + + + public function clone ():Library { + + return new Library (sourcePath, name, type, embed, preload, generate, prefix); + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/MetaData.hx b/src/lime/tools/MetaData.hx new file mode 100644 index 000000000..a04402bd6 --- /dev/null +++ b/src/lime/tools/MetaData.hx @@ -0,0 +1,15 @@ +package lime.tools; + + +typedef MetaData = { + + @:optional var buildNumber:String; + @:optional var company:String; + @:optional var companyId:String; + @:optional var companyUrl:String; + @:optional var description:String; + @:optional var packageName:String; + @:optional var title:String; + @:optional var version:String; + +} \ No newline at end of file diff --git a/src/lime/tools/ModuleData.hx b/src/lime/tools/ModuleData.hx new file mode 100644 index 000000000..786f6383e --- /dev/null +++ b/src/lime/tools/ModuleData.hx @@ -0,0 +1,57 @@ +package lime.tools; + + +import hxp.ArrayHelper; + + +class ModuleData { + + + public var classNames:Array; + public var excludeTypes:Array; + public var haxeflags:Array; + public var includeTypes:Array; + public var name:String; + + + public function new (name:String) { + + this.name = name; + classNames = []; + excludeTypes = []; + haxeflags = []; + includeTypes = []; + + } + + + public function clone ():ModuleData { + + var copy = new ModuleData (name); + copy.classNames = classNames.copy (); + copy.excludeTypes = excludeTypes.copy (); + copy.haxeflags = haxeflags.copy (); + copy.includeTypes = includeTypes.copy (); + return copy; + + } + + + public function merge (other:ModuleData):Bool { + + if (other.name == name) { + + classNames = ArrayHelper.concatUnique (classNames, other.classNames); + excludeTypes = ArrayHelper.concatUnique (excludeTypes, other.excludeTypes); + haxeflags = ArrayHelper.concatUnique (haxeflags, other.haxeflags); + includeTypes = ArrayHelper.concatUnique (includeTypes, other.includeTypes); + return true; + + } + + return false; + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/ModuleHelper.hx b/src/lime/tools/ModuleHelper.hx new file mode 100644 index 000000000..dbdfd920b --- /dev/null +++ b/src/lime/tools/ModuleHelper.hx @@ -0,0 +1,726 @@ +package lime.tools; #if !macro + + +import haxe.io.Path; +import lime.tools.Dependency; +import hxp.Haxelib; +import hxp.*; +import lime.tools.Project; +import lime.tools.ModuleData; +import sys.io.File; +import sys.FileSystem; + + +class ModuleHelper { + + + public static function addModuleSource (source:String, moduleData:ModuleData, include:Array, exclude:Array, packageName:String = null) { + + if (!FileSystem.exists (source)) { + + Log.error ("Could not find module source \"" + source + "\""); + return; + + } + + moduleData.haxeflags.push ("-cp " + source); + + var path = source; + + if (packageName != null && packageName.length > 0) { + + path = PathHelper.combine (source, StringTools.replace (packageName, ".", "/")); + + } + + parseModuleSource (source, moduleData, include, exclude, path); + + } + + + public static function buildModules (project:Project, tempDirectory:String, outputDirectory:String):Void { + + tempDirectory = PathHelper.combine (tempDirectory, "lib"); + outputDirectory = PathHelper.combine (outputDirectory, "lib"); + + PathHelper.mkdir (tempDirectory); + PathHelper.mkdir (outputDirectory); + + var importName, hxmlPath, importPath, outputPath, moduleImport, hxml; + + for (module in project.modules) { + + if (module.classNames.length > 0) { + + importName = "Module" + module.name.charAt (0).toUpperCase () + module.name.substr (1); + + hxmlPath = PathHelper.combine (tempDirectory, module.name + ".hxml"); + importPath = PathHelper.combine (tempDirectory, importName + ".hx"); + + if (project.targetFlags.exists ("final")) { + + outputPath = PathHelper.combine (outputDirectory, module.name + ".min.js"); + + } else { + + outputPath = PathHelper.combine (outputDirectory, module.name + ".js"); + + } + + moduleImport = "package;\n\nimport " + module.classNames.join (";\nimport ") + ";"; + + hxml = "-cp " + tempDirectory; + hxml += "\n" + module.haxeflags.join ("\n"); + + for (haxelib in project.haxelibs) { + + hxml += "\n-cp " + PathHelper.getHaxelib (haxelib); + + } + + for (key in project.haxedefs.keys ()) { + + if (key != "no-compilation") { + + var value = project.haxedefs.get (key); + + if (value == null || value == "") { + + hxml += "\n-D " + key; + + } else { + + hxml += "\n-D " + key + "=" + value; + + } + + } + + } + + hxml += "\n-D html5"; + hxml += "\n-D html"; + hxml += "\n--no-inline"; + hxml += "\n-dce no"; + hxml += "\n-js " + outputPath; + + var includeTypes = module.classNames.concat (module.includeTypes); + var excludeTypes = module.excludeTypes; + + for (otherModule in project.modules) { + + if (otherModule != module) { + + excludeTypes = excludeTypes.concat (ArrayHelper.getUnique (includeTypes, otherModule.classNames)); + excludeTypes = excludeTypes.concat (ArrayHelper.getUnique (includeTypes, otherModule.includeTypes)); + + } + + } + + if (excludeTypes.length > 0) { + + // order by short filters first, so they match earlier + haxe.ds.ArraySort.sort(excludeTypes, shortFirst); + hxml += "\n--macro lime.tools.ModuleHelper.exclude(['" + excludeTypes.join ("','") + "'])"; + + } + + // order by short filters first, so they match earlier + haxe.ds.ArraySort.sort(includeTypes, shortFirst); + hxml += "\n--macro lime.tools.ModuleHelper.expose(['" + includeTypes.join ("','") + "'])"; + //hxml += "\n--macro lime.tools.ModuleHelper.generate()"; + + hxml += "\n" + importName; + + File.saveContent (importPath, moduleImport); + File.saveContent (hxmlPath, hxml); + + ProcessHelper.runCommand ("", "haxe", [ hxmlPath ]); + + patchFile (outputPath); + + if (project.targetFlags.exists ("final")) { + + HTML5Helper.minify (project, outputPath); + + } + + } + + } + + } + + + private static function parseModuleSource (source:String, moduleData:ModuleData, include:Array, exclude:Array, currentPath:String):Void { + + var files = FileSystem.readDirectory (currentPath); + var filePath:String, className:String, packageName:String; + + for (file in files) { + + filePath = PathHelper.combine (currentPath, file); + + if (FileSystem.isDirectory (filePath)) { + + packageName = StringTools.replace (filePath, source, ""); + packageName = StringTools.replace (packageName, "\\", "/"); + + while (StringTools.startsWith (packageName, "/")) packageName = packageName.substr (1); + + packageName = StringTools.replace (packageName, "/", "."); + + if (StringHelper.filter (packageName, include, exclude)) { + + parseModuleSource (source, moduleData, include, exclude, filePath); + + } + + } else { + + if (Path.extension (file) != "hx") continue; + + className = StringTools.replace (filePath, source, ""); + className = StringTools.replace (className, "\\", "/"); + + while (StringTools.startsWith (className, "/")) className = className.substr (1); + + className = StringTools.replace (className, "/", "."); + className = StringTools.replace (className, ".hx", ""); + + if (StringHelper.filter (className, include, exclude)) { + + moduleData.classNames.push (className); + + } + + } + + } + + } + + + public static function patchFile (outputPath:String):Void { + + var replaceString = "var $hxClasses = {}"; + var replacement = "if (!$hx_exports.$hxClasses) $hx_exports.$hxClasses = {};\nvar $hxClasses = $hx_exports.$hxClasses"; + + FileHelper.replaceText (outputPath, replaceString, replacement); + + } + + + public static function updateProject (project:Project):Void { + + var excludeTypes = []; + var suffix = (project.targetFlags.exists ("final") ? ".min" : "") + ".js"; + var hasModules = false; + + for (module in project.modules) { + + project.dependencies.push (new Dependency ("./lib/" + module.name + suffix, null)); + + excludeTypes = ArrayHelper.concatUnique (excludeTypes, module.classNames); + excludeTypes = ArrayHelper.concatUnique (excludeTypes, module.excludeTypes); + excludeTypes = ArrayHelper.concatUnique (excludeTypes, module.includeTypes); + + hasModules = true; + + } + + if (excludeTypes.length > 0) { + + // order by short filters first, so they match earlier + haxe.ds.ArraySort.sort(excludeTypes, shortFirst); + project.haxeflags.push ("--macro lime.tools.ModuleHelper.exclude(['" + excludeTypes.join ("','") + "'])"); + + } + + //if (hasModules) { + // + //project.haxeflags.push ("--macro lime.tools.ModuleHelper.generate()"); + // + //} + + } + + + public static function shortFirst(a, b):Int { + if (a.length < b.length) return -1; + else if (a.length > b.length) return 1; + return 0; + } + + +} + + +#else + + +import haxe.macro.Compiler; +import haxe.macro.Context; +import haxe.macro.Type; +import haxe.macro.Expr; +import haxe.macro.JSGenApi; +using haxe.macro.Tools; + +using Lambda; +using StringTools; + + +class ModuleHelper { + + + public static function exclude (types:Array):Void { + + for (type in types) { + + Compiler.exclude (type); + Compiler.addMetadata ("@:native(\"$hx_exports." + type + "\")", type); + + } + + } + + + public static function expose (classNames:Array):Void { + + for (className in classNames) { + + Compiler.addMetadata ("@:expose('" + className + "')", className); + + } + + } + + + public static function generate() { + + //Compiler.setCustomJSGenerator(function(api) new Generator(api).generate()); + + } + + +} + + +class Generator { + + var api : JSGenApi; + var buf : StringBuf; + var inits : List; + var statics : List<{ c : ClassType, f : ClassField }>; + var packages : haxe.ds.StringMap; + var forbidden : haxe.ds.StringMap; + var jsModern:Bool; + var jsFlatten:Bool; + var dce:Bool; + var indentLevel=0; + var genExtend=false; + var genExpose=false; + + var iRE=~/^(.*)$/gm; + + public function new(api) { + this.api = api; + buf = new StringBuf(); + inits = new List(); + statics = new List(); + packages = new haxe.ds.StringMap(); + forbidden = new haxe.ds.StringMap(); + jsModern=!Context.defined("js-classic"); + jsFlatten=!Context.defined("js-unflatten"); + dce=Context.definedValue("dce")!="no"; + for( x in ["prototype", "__proto__", "constructor"] ) + forbidden.set(x, true); + api.setTypeAccessor(getType); + + for (t in api.types){ + switch (t) { + case TInst(c,_): + if (!c.get().isExtern && c.get().superClass!=null) + genExtend=true; + if (c.get().meta.has(":expose")) + genExpose=true; + if (genExtend && genExpose) break; + case _: + } + } + } + + function getType( t : Type ) { + return switch(t) { + case TInst(c, _): getPath(c.get()); + case TEnum(e, _): getPath(e.get()); + case TAbstract(a, _): getPath(a.get()); + default: throw "assert"; + }; + } + inline function indent(str:String,level=0,notFirst=false):String{ + var first=true; + var lines=str.split("\n"); + var nstr=""; + for (i in 0...lines.length){ + var s=lines[i]; + if (first && notFirst){ + first=false; + nstr+=s; + }else{ + for (i in 0...level){ + nstr+='\t'; + } + nstr+='$s'; + } + if (i ) { + if (p.length==0) + print("var "); + var full = null; + for( x in p ) { + var prev = full; + if( full == null ) full = x else full += "." + x; + if( packages.exists(full) ) + continue; + packages.set(full, true); + if( prev == null ) + println('var $x = '+(jsModern?"{}":'$x || {}') ); + else { + var p = prev + field(x); + println((jsModern?'':'if(!$p) ')+'$p = {}'); + } + } + } + + function getPath( t : BaseType ) { + return packClass(t.pack,t.name); + } + function getDotPath( t : BaseType ) { + return (t.pack.length == 0) ? t.name : t.pack.join('.') + '.' + t.name; + } + + function packClass(p:Array,name:String){ + if (jsFlatten){ + var r=''; + for (i in p){ + r+=i.replace("_","_$")+'_'; + } + return r+name.replace("_","_$"); + } + return (p.length == 0) ? name : p.join('.') + '.' + name; + } + + function checkFieldName( c : ClassType, f : ClassField ) { + if( forbidden.exists(f.name) ) + Context.error("The field " + f.name + " is not allowed in JS", c.pos); + } + + function genClassField( c : ClassType, p : String, f : ClassField , first:Bool) { + checkFieldName(c, f); + var field = field(f.name,false); + var e=f.expr(); + if (e!=null){ + printin((first?"":",")+'$field: '+api.generateValue(e) ,indentLevel,false); + return false; + }else if (!dce && (f.kind.match(FVar(AccNormal, AccNormal) | FMethod(_)) || f.meta.has(":isVar"))){ + printin((first?"":",")+'$field: null' ,indentLevel,false); + return false; + } + return first; + } + + + function genStaticField( c : ClassType, p : String, f : ClassField ) { + checkFieldName(c, f); + var field = field(f.name); + var e = f.expr(); + if( e != null ) { + switch( f.kind ) { + case FMethod(_): + print('$p$field = '); + println(api.generateValue(e)); + default: + statics.add( { c : c, f : f } ); + } + } else{ + if (!dce && (f.kind.match(FVar(AccNormal, AccNormal) | FMethod(_)) || f.meta.has(":isVar"))) + println('$p$field = null'); + } + } + + function getProperties(fields:Array):String{ + var properties=[]; + for (f in fields){ + switch (f.kind) { + case FVar(g,s):{ + if (g==AccCall) + properties.push('get_${f.name}:"get_${f.name}"'); + if (s==AccCall) + properties.push('set_${f.name}:"set_${f.name}"'); + } + case _: + } + } + return (properties.length>0)?('{'+properties.join(",")+'}'):""; + } + + + function genClass( c : ClassType ) { + api.setCurrentClass(c); + + var hxClasses=api.hasFeature("Type.resolveClass"); + var p = getPath(c); + var pn= getDotPath(c); + if (jsFlatten) + print("var "); + else + genPackage(c.pack); + + if (hxClasses && !jsModern) + print('$p = $$hxClasses["$pn"] = '); + else + print('$p = '+(c.meta.has(":expose")?'$$hx_exports.$p = ':'')); + if( c.constructor != null ) + print(api.generateValue(c.constructor.get().expr())); + else + print("function() { }"); + newline(); + if (hxClasses && jsModern) + println('$$hxClasses["$pn"] = $p'); + + var name = pn.split(".").map(api.quoteString).join(","); + if (api.hasFeature("js.Boot.isClass")){ + if (api.hasFeature("Type.getClassName")) + println('$p.__name__ = [$name]'); + else + println('$p.__name__ = true'); + } + if( c.interfaces.length > 0 ) { + var me = this; + var inter = c.interfaces.map(function(i) return me.getPath(i.t.get())).join(","); + print('$p.__interfaces__ = [$inter]'); + newline(); + } + var has_property_reflection =api.hasFeature("Reflect.getProperty") || api.hasFeature("Reflect.setProperty"); + + if (has_property_reflection){ + var staticProperties=getProperties(c.statics.get()); + if (staticProperties.length>0) + printn('$p.__properties__ = $staticProperties'); + } + for( f in c.statics.get() ) + genStaticField(c, p, f); + + var has_class = api.hasFeature("js.Boot.getClass") && (c.superClass != null || c.fields.get().length > 0 || c.constructor != null); + var has_prototype = has_class || c.superClass != null || c.fields.get().length > 0; + + if (has_prototype){ + if( c.superClass != null ) { + var psup = getPath(c.superClass.t.get()); + println('$p.__super__ = $psup'); + printn('$p.prototype = $$extend($psup.prototype,{'); + }else{ + printn('$p.prototype = {'); + } + indentLevel++; + var first=true; + for( f in c.fields.get() ) { + switch( f.kind ) { + case FVar(r, _): + if( r == AccResolve ) continue; + default: + } + first=genClassField(c, p, f, first); + } + if (has_class){ + if(!first) + print(","); + printi('__class__: $p\n'); + } + if (has_property_reflection){ + var properties=getProperties(c.fields.get()); + if (properties.length>0) + if( c.superClass != null ) { + var psup = getPath(c.superClass.t.get()); + printn((first?"":",")+'__properties__: $$extend($psup.prototype.__properties__,$properties)'); + } else + printn((first?"":",")+'__properties__: $properties'); + } + indentLevel--; + if( c.superClass != null ) + printin("});",0); + else + printin("};",0); + } + + + } + + function genEnum( e : EnumType ) { + var p = getPath(e); + var pn= getDotPath(e); + var names = pn.split(".").map(api.quoteString).join(","); + var constructs = e.names.map(api.quoteString).join(","); + var hxClasses=api.hasFeature("Type.resolveEnum"); + + if (jsFlatten) + print("var "); + else + genPackage(e.pack); + + if (hxClasses) + print('$p = $$hxClasses["$pn"] = {'); + else + print('$p = {'); + + if (api.hasFeature("js.Boot.isEnum")) + if (api.hasFeature("Type.getEnumName")) + print(' __ename__ : [$names],'); + else + print(' __ename__ : true,'); + println(' __constructs__ : [$constructs] }'); + for( c in e.constructs.keys() ) { + var c = e.constructs.get(c); + var f = field(c.name); + print('$p$f = '); + switch( c.type ) { + case TFun(args, _): + var sargs = args.map(function(a) return a.name).join(","); + print('function($sargs) { var $$x = ["${c.name}",${c.index},$sargs]; $$x.__enum__ = $p; $$x.toString = $$estr; return $$x; }'); + default: + println("[" + api.quoteString(c.name) + "," + c.index + "]"); + if (api.hasFeature("may_print_enum")) + println('$p$f.toString = $$estr'); + print('$p$f.__enum__ = $p'); + } + newline(); + } + if (api.hasFeature("Type.allEnums")){ + var ec=Lambda.fold(e.constructs, function(c:EnumField, r:Array) { + if (!c.type.match(TFun(_,_))) + r.push('$p.${c.name}'); + return r; + }, []); + if (ec.length>0) + println('$p.__empty_constructs__ = ['+ec.join(",")+']'); + } + var meta = api.buildMetaData(e); + if( meta != null ) { + print('$p.__meta__ = '); + println(api.generateValue(meta)); + } + } + + function genType( t : Type ) { + switch( t ) { + case TInst(c, _): + var c = c.get(); + if( c.init != null ) + inits.add(c.init); + if( !c.isExtern ) genClass(c); + case TEnum(r, _): + var e = r.get(); + if( !e.isExtern ) genEnum(e); + default: + } + } + + public function generate() { + if (jsModern) + println('(function ('+(genExpose?"$hx_exports":"")+", $global) { \"use strict\""); + + if (jsModern) + println("if (!$hx_exports.$hxClasses) $hx_exports.$hxClasses = {}"); + + var vars = []; + if (api.hasFeature("Type.resolveClass") || api.hasFeature("Type.resolveEnum")) + //vars.push("$hxClasses = " + (jsModern? "{}" : "$hxClasses || {}")); + vars.push("$hxClasses = " + (jsModern? "$hx_exports.$hxClasses" : "$hxClasses || {}")); + if (api.hasFeature("may_print_enum")) + vars.push("$estr = function() { return "+packClass(["js"],"Boot")+".__string_rec(this,''); }"); + if (vars.length>0) + println("var "+vars.join(",")); + + if(genExtend) + print("function $extend(from, fields) { + function Inherit() {} Inherit.prototype = from; var proto = new Inherit(); + for (var name in fields) proto[name] = fields[name]; + if( fields.toString !== Object.prototype.toString ) proto.toString = fields.toString; + return proto; +}\n"); + + for( t in api.types ) + genType(t); + + if (api.hasFeature("use.$iterator")){ + api.addFeature("use.$bind"); + printn("function $iterator(o) { if( o instanceof Array ) return function() { return HxOverrides.iter(o); }; return typeof(o.iterator) == 'function' ? $bind(o,o.iterator) : o.iterator; }"); + } + if (api.hasFeature("use.$bind")){ + println("var $_, $fid = 0"); + printn("function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $fid++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = function(){ return f.method.apply(f.scope, arguments); }; f.scope = o; f.method = m; o.hx__closures__[m.__id__] = f; } return f; }"); + } + for( e in inits ) + genInit(e); + for( s in statics ) + println(getPath(s.c)+field(s.f.name)+' = '+api.generateValue(s.f.expr())); + if( api.main != null ) + println(api.generateValue(api.main)); + if (jsModern) + print('})('+(genExpose?'typeof exports != "undefined" ? exports : typeof window != "undefined" ? window : typeof self != "undefined" ? self : this, ':'')+'typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this);\n'); + sys.io.File.saveContent(api.outputFile, buf.toString()); + } + + function genInit(e:TypedExpr){ + var code=api.generateStatement(e); + //cosmetic only + var colon=';'; + for (l in code.split('\n')){ + if (l=="{" || l=="}") { + colon=''; + continue; + } + printn(l.replace("\t","")+colon); + } + } + +} + + +#end \ No newline at end of file diff --git a/src/lime/tools/NekoHelper.hx b/src/lime/tools/NekoHelper.hx new file mode 100644 index 000000000..f08b9f54b --- /dev/null +++ b/src/lime/tools/NekoHelper.hx @@ -0,0 +1,85 @@ +package lime.tools; + + +import haxe.io.Path; +import hxp.PlatformHelper; +import hxp.Haxelib; +import lime.tools.Platform; +import hxp.*; +import sys.FileSystem; +import sys.io.File; + + +class NekoHelper { + + + public static function copyLibraries (templatePaths:Array, platformName:String, targetPath:String) { + + //FileHelper.recursiveCopyTemplate (templatePaths, "neko/ndll/" + platformName, targetPath); + + } + + + public static function createExecutable (templatePaths:Array, platformName:String, source:String, target:String, iconPath:String = null):Void { + + /*var executablePath = PathHelper.findTemplate (templatePaths, "neko/bin/neko-" + platformName); + var executable = File.getBytes (executablePath); + var sourceContents = File.getBytes (source); + + var output = File.write (target, true); + output.write (executable); + output.write (sourceContents); + output.writeString ("NEKO"); + output.writeInt32 (executable.length); + output.close ();*/ + + var path = PathHelper.tryFullPath (source); + var file = Path.withoutDirectory (path); + var dir = Path.directory (path); + + ProcessHelper.runCommand (dir, "nekotools", [ "boot", file ]); + + var path = Path.withoutExtension (source); + + if (PlatformHelper.hostPlatform == WINDOWS) { + + path += ".exe"; + + } + + FileHelper.copyFile (path, target); + + } + + + public static function createWindowsExecutable (templatePaths:Array, source:String, target:String, iconPath:String):Void { + + /*var executablePath = PathHelper.findTemplate (templatePaths, "neko/bin/neko-windows"); + var executable = File.getBytes (executablePath); + var sourceContents = File.getBytes (source); + + var output = File.write (target, true); + output.write (executable); + output.close (); + + if (iconPath != null && PlatformHelper.hostPlatform == WINDOWS) { + + var templates = [ PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)) + "/templates" ].concat (templatePaths); + ProcessHelper.runCommand ("", PathHelper.findTemplate (templates, "bin/ReplaceVistaIcon.exe"), [ target, iconPath, "1" ], true, true); + + } + + var executable = File.getBytes (target); + var output = File.write (target, true); + output.write (executable); + output.write (sourceContents); + output.writeString ("NEKO"); + output.writeInt32 (executable.length); + output.close ();*/ + + createExecutable (templatePaths, null, source, target, iconPath); + + } + + +} diff --git a/src/lime/tools/NodeJSHelper.hx b/src/lime/tools/NodeJSHelper.hx new file mode 100644 index 000000000..e62c52deb --- /dev/null +++ b/src/lime/tools/NodeJSHelper.hx @@ -0,0 +1,62 @@ +package lime.tools; + + +import haxe.io.Path; +import lime.tools.Architecture; +import hxp.Haxelib; +import lime.tools.Project; +import lime.tools.Platform; +import hxp.*; + + +class NodeJSHelper { + + + public static function run (project:Project, modulePath:String, args:Array = null):Void { + + /*var suffix = switch (PlatformHelper.hostPlatform) { + + case Platform.WINDOWS: "-windows.exe"; + case Platform.MAC: "-mac"; + case Platform.LINUX: "-linux"; + default: return; + + } + + if (suffix == "-linux") { + + if (PlatformHelper.hostArchitecture == X86) { + + suffix += "32"; + + } else { + + suffix += "64"; + + } + + } + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), "templates") ].concat (project.templatePaths); + var node = PathHelper.findTemplate (templatePaths, "bin/node/node" + suffix); + + if (PlatformHelper.hostPlatform != WINDOWS) { + + Sys.command ("chmod", [ "+x", node ]); + + } + + if (args == null) { + + args = []; + + }*/ + + args.unshift (Path.withoutDirectory (modulePath)); + + ProcessHelper.runCommand (Path.directory (modulePath), "node", args); + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/Orientation.hx b/src/lime/tools/Orientation.hx new file mode 100644 index 000000000..9431b714e --- /dev/null +++ b/src/lime/tools/Orientation.hx @@ -0,0 +1,11 @@ +package lime.tools; + + +enum Orientation { + + PORTRAIT; + LANDSCAPE; + ALL; + AUTO; + +} \ No newline at end of file diff --git a/src/lime/tools/Platform.hx b/src/lime/tools/Platform.hx new file mode 100644 index 000000000..40b7b146f --- /dev/null +++ b/src/lime/tools/Platform.hx @@ -0,0 +1,28 @@ +package lime.tools; + + +@:enum abstract Platform(String) { + + var AIR = "air"; + var ANDROID = "android"; + var BLACKBERRY = "blackberry"; + var CONSOLE_PC = "console-pc"; + var FIREFOX = "firefox"; + var FLASH = "flash"; + var HTML5 = "html5"; + var IOS = "ios"; + var LINUX = "linux"; + var MAC = "mac"; + var PS3 = "ps3"; + var PS4 = "ps4"; + var TIZEN = "tizen"; + var VITA = "vita"; + var WINDOWS = "windows"; + var WEBOS = "webos"; + var WIIU = "wiiu"; + var XBOX1 = "xbox1"; + var EMSCRIPTEN = "emscripten"; + var TVOS = "tvos"; + var CUSTOM = null; + +} diff --git a/src/lime/tools/PlatformTarget.hx b/src/lime/tools/PlatformTarget.hx new file mode 100644 index 000000000..9d1941313 --- /dev/null +++ b/src/lime/tools/PlatformTarget.hx @@ -0,0 +1,179 @@ +package lime.tools; + + +import haxe.rtti.Meta; +import lime.tools.AssetHelper; +import lime.tools.CommandHelper; +import hxp.Log; + + +class PlatformTarget { + + + public var additionalArguments:Array; + public var buildType:String; + public var command:String; + public var noOutput:Bool; + public var project:Project; + public var targetDirectory:String; + public var targetFlags:Map; + public var traceEnabled = true; + + + public function new (command:String = null, project:Project = null, targetFlags:Map = null) { + + this.command = command; + this.project = project; + this.targetFlags = targetFlags; + + buildType = "release"; + + if (project != null) { + + if (project.debug) { + + buildType = "debug"; + + } else if (project.targetFlags.exists ("final")) { + + buildType = "final"; + + } + + } + + for (haxeflag in project.haxeflags) { + + if (haxeflag == "--no-output") { + + noOutput = true; + + } + + } + + } + + + public function execute (additionalArguments:Array):Void { + + // Log.info ("", Log.accentColor + "Using target platform: " + Std.string (project.target).toUpperCase () + Log.resetColor); + + this.additionalArguments = additionalArguments; + var metaFields = Meta.getFields (Type.getClass (this)); + + if (/*!Reflect.hasField (metaFields.watch, "ignore") && */(project.targetFlags.exists ("watch"))) { + + Log.info ("", "\n" + Log.accentColor + "Running command: WATCH" + Log.resetColor); + watch (); + return; + + } + + if ((!Reflect.hasField (metaFields, "display") || !Reflect.hasField (metaFields.display, "ignore")) && (command == "display")) { + + display (); + + } + + //if (!Reflect.hasField (metaFields.clean, "ignore") && (command == "clean" || targetFlags.exists ("clean"))) { + if ((!Reflect.hasField (metaFields, "clean") || !Reflect.hasField (metaFields.clean, "ignore")) && (command == "clean" || (project.targetFlags.exists ("clean") && (command == "update" || command == "build" || command == "test")))) { + + Log.info ("", Log.accentColor + "Running command: CLEAN" + Log.resetColor); + clean (); + + } + + if ((!Reflect.hasField (metaFields, "rebuild") || !Reflect.hasField (metaFields.rebuild, "ignore")) && (command == "rebuild" || project.targetFlags.exists ("rebuild"))) { + + Log.info ("", "\n" + Log.accentColor + "Running command: REBUILD" + Log.resetColor); + + // hack for now, need to move away from project.rebuild.path, probably + + if (project.targetFlags.exists ("rebuild")) { + + project.config.set ("project.rebuild.path", null); + + } + + rebuild (); + + } + + if ((!Reflect.hasField (metaFields, "update") || !Reflect.hasField (metaFields.update, "ignore")) && (command == "update" || command == "build" || command == "test")) { + + Log.info ("", "\n" + Log.accentColor + "Running command: UPDATE" + Log.resetColor); + // #if lime + // AssetHelper.processLibraries (project, targetDirectory); + // #end + update (); + + } + + if ((!Reflect.hasField (metaFields, "build") || !Reflect.hasField (metaFields.build, "ignore")) && (command == "build" || command == "test")) { + + CommandHelper.executeCommands (project.preBuildCallbacks); + + Log.info ("", "\n" + Log.accentColor + "Running command: BUILD" + Log.resetColor); + build (); + + CommandHelper.executeCommands (project.postBuildCallbacks); + + } + + if ((!Reflect.hasField (metaFields, "deploy") || !Reflect.hasField (metaFields.deploy, "ignore")) && (command == "deploy")) { + + Log.info ("", "\n" + Log.accentColor + "Running command: DEPLOY" + Log.resetColor); + deploy (); + + } + + if ((!Reflect.hasField (metaFields, "install") || !Reflect.hasField (metaFields.install, "ignore")) && (command == "install" || command == "run" || command == "test")) { + + Log.info ("", "\n" + Log.accentColor + "Running command: INSTALL" + Log.resetColor); + install (); + + } + + if ((!Reflect.hasField (metaFields, "run") || !Reflect.hasField (metaFields.run, "ignore")) && (command == "run" || command == "rerun" || command == "test")) { + + Log.info ("", "\n" + Log.accentColor + "Running command: RUN" + Log.resetColor); + run (); + + } + + if ((!Reflect.hasField (metaFields, "trace") || !Reflect.hasField (metaFields.trace, "ignore")) && (command == "test" || command == "trace" || command == "run" || command == "rerun" )) { + + if (traceEnabled || command == "trace") { + + Log.info ("", "\n" + Log.accentColor + "Running command: TRACE" + Log.resetColor); + this.trace (); + + } + + } + + if ((!Reflect.hasField (metaFields, "uninstall") || !Reflect.hasField (metaFields.uninstall, "ignore")) && (command == "uninstall")) { + + Log.info ("", "\n" + Log.accentColor + "Running command: UNINSTALL" + Log.resetColor); + uninstall (); + + } + + } + + + @ignore public function build ():Void {} + @ignore public function clean ():Void {} + @ignore public function deploy ():Void {} + @ignore public function display ():Void {} + @ignore public function install ():Void {} + @ignore public function rebuild ():Void {} + @ignore public function run ():Void {} + @ignore public function trace ():Void {} + @ignore public function uninstall ():Void {} + @ignore public function update ():Void {} + @ignore public function watch ():Void {} + + +} \ No newline at end of file diff --git a/src/lime/tools/PlatformTargetMain.hx b/src/lime/tools/PlatformTargetMain.hx new file mode 100644 index 000000000..a7caccf2a --- /dev/null +++ b/src/lime/tools/PlatformTargetMain.hx @@ -0,0 +1,176 @@ +package lime.tools; + + +import haxe.io.Path; +import haxe.Unserializer; +import lime.tools.Architecture; +import hxp.Haxelib; +import lime.tools.Project; +import lime.tools.Platform; +import hxp.HaxelibHelper; +import hxp.Log; +import hxp.PathHelper; +import hxp.PlatformHelper; +import sys.io.File; +import sys.io.Process; +import sys.FileSystem; + + +class PlatformTargetMain { + + + private static var additionalArguments = new Array (); + private static var targetFlags = new Map (); + private static var traceEnabled:Bool = true; + + + public static function main () { + + var arguments = Sys.args (); + var runFromHaxelib = false; + + if (arguments.length > 0) { + + // When the command-line tools are called from haxelib, + // the last argument is the project directory and the + // path to Lime is the current working directory + + var lastArgument = ""; + + for (i in 0...arguments.length) { + + lastArgument = arguments.pop (); + if (lastArgument.length > 0) break; + + } + + lastArgument = new Path (lastArgument).toString (); + + if (((StringTools.endsWith (lastArgument, "/") && lastArgument != "/") || StringTools.endsWith (lastArgument, "\\")) && !StringTools.endsWith (lastArgument, ":\\")) { + + lastArgument = lastArgument.substr (0, lastArgument.length - 1); + + } + + if (FileSystem.exists (lastArgument) && FileSystem.isDirectory (lastArgument)) { + + Sys.setCwd (lastArgument); + runFromHaxelib = true; + + } else { + + arguments.push (lastArgument); + + } + + } + + if (!runFromHaxelib) { + + if (FileSystem.exists ("tools.n")) { + + HaxelibHelper.setOverridePath (new Haxelib("lime"), PathHelper.combine (Sys.getCwd (), "../")); + + } else if (FileSystem.exists ("run.n")) { + + HaxelibHelper.setOverridePath (new Haxelib("lime"), Sys.getCwd ()); + + } + + } + + var additionalArguments = []; + var catchArguments = false; + var className = ""; + var command = ""; + var words = []; + + for (argument in arguments) { + + var equals = argument.indexOf ("="); + + if (catchArguments) { + + additionalArguments.push (argument); + + } else if (argument == "-v" || argument == "-verbose") { + + Log.verbose = true; + + } else if (argument == "-args") { + + catchArguments = true; + + } else if (argument == "-notrace") { + + traceEnabled = false; + + } else if (argument == "-debug") { + + //debug = true; + + } else if (argument == "-nocolor") { + + Log.enableColor = false; + + } else if (className.length == 0) { + + className = argument; + + } else if (command.length == 0) { + + command = argument; + + } else { + + words.push (argument); + + } + + } + + if (words.length > 0) { + + try { + + var classRef = Type.resolveClass (className); + if (classRef == null) throw "Cannot find class name \"" + className + "\""; + + var inputPath = words[0]; + var projectData = File.getContent (inputPath); + + var unserializer = new Unserializer (projectData); + unserializer.setResolver (cast { resolveEnum: Type.resolveEnum, resolveClass: resolveClass }); + var project:Project = unserializer.unserialize (); + + var platform = Type.createInstance (classRef, [ command, project, project.targetFlags ]); + platform.traceEnabled = traceEnabled; + platform.execute (additionalArguments); + + } catch (e:Dynamic) { + + Log.error (e); + + } + + } + + } + + + private static function resolveClass (name:String):Class { + + var result = Type.resolveClass (name); + + if (result == null) { + + result = Project; + + } + + return result; + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/PlatformType.hx b/src/lime/tools/PlatformType.hx new file mode 100644 index 000000000..22a753299 --- /dev/null +++ b/src/lime/tools/PlatformType.hx @@ -0,0 +1,11 @@ +package lime.tools; + + +enum PlatformType { + + DESKTOP; + MOBILE; + WEB; + CONSOLE; + +} \ No newline at end of file diff --git a/src/lime/tools/Project.hx b/src/lime/tools/Project.hx new file mode 100644 index 000000000..c1f4acd7c --- /dev/null +++ b/src/lime/tools/Project.hx @@ -0,0 +1,1601 @@ +package lime.tools; + + +import haxe.io.Eof; +import haxe.io.Path; +import haxe.xml.Fast; +import haxe.Json; +import haxe.Serializer; +import haxe.Unserializer; +import lime.tools.Architecture; +import hxp.ArrayHelper; +import hxp.FileHelper; +import hxp.Haxelib; +import hxp.HaxelibHelper; +import hxp.Log; +import hxp.NDLL; +import hxp.ObjectHelper; +import hxp.PathHelper; +import lime.tools.Platform; +import hxp.PlatformHelper; +import hxp.ProcessHelper; +import hxp.Script; +import hxp.StringHelper; +import hxp.StringMapHelper; +import lime.tools.AssetType; +import sys.FileSystem; +import sys.io.File; +import sys.io.Process; + +#if (lime && lime_cffi && !macro) +import lime.text.Font; +@:access(lime.text.Font) +#end + + +class Project extends Script { + + + public var app:ApplicationData; + public var architectures:Array; + public var assets:Array; + // public var command:String; + public var config:ConfigData; + public var debug:Bool; + // public var defines:Map; + public var dependencies:Array; + public var environment:Map; + public var haxedefs:Map; + public var haxeflags:Array; + public var haxelibs:Array; + public var host (get_host, null):Platform; + public var icons:Array; + public var javaPaths:Array; + public var keystore:Keystore; + public var languages:Array; + public var libraries:Array; + public var libraryHandlers:Map; + public var meta:MetaData; + public var modules:Map; + public var ndlls:Array; + public var platformType:PlatformType; + public var postBuildCallbacks:Array; + public var preBuildCallbacks:Array; + public var samplePaths:Array; + public var sources:Array; + public var splashScreens:Array; + public var target:Platform; + public var targetFlags:Map; + public var targetHandlers:Map; + public var templateContext (get_templateContext, null):Dynamic; + public var templatePaths:Array; + @:isVar public var window (get, set):WindowData; + public var windows:Array; + + private var defaultApp:ApplicationData; + private var defaultArchitectures:Array; + private var defaultMeta:MetaData; + private var defaultWindow:WindowData; + private var needRerun:Bool; + + public static var _command:String; + public static var _debug:Bool; + public static var _environment:Map; + public static var _target:Platform; + public static var _targetFlags:Map; + public static var _templatePaths:Array; + public static var _userDefines:Map; + + private static var initialized:Bool; + + + public static function main () { + + var args = Sys.args (); + + if (args.length < 2) { + + return; + + } + + var inputData = Unserializer.run (File.getContent (args[0])); + var outputFile = args[1]; + + Project._command = inputData.command; + Project._target = cast inputData.target; + Project._debug = inputData.debug; + Project._targetFlags = inputData.targetFlags; + Project._templatePaths = inputData.templatePaths; + Project._userDefines = inputData.userDefines; + Project._environment = inputData.environment; + Log.verbose = inputData.logVerbose; + Log.enableColor = inputData.logEnableColor; + + #if lime + ProcessHelper.dryRun = inputData.processDryRun; + #end + + HaxelibHelper.debug = inputData.haxelibDebug; + + initialize (); + + var classRef = Type.resolveClass (inputData.name); + var instance = Type.createInstance (classRef, []); + + var serializer = new Serializer (); + serializer.useCache = true; + serializer.serialize (instance); + + File.saveContent (outputFile, serializer.toString ()); + + } + + + public function new () { + + super (); + + initialize (); + + command = _command; + config = new ConfigData (); + debug = _debug; + target = _target; + targetFlags = StringMapHelper.copy (_targetFlags); + templatePaths = _templatePaths.copy (); + + defaultMeta = { title: "MyApplication", description: "", packageName: "com.example.myapp", version: "1.0.0", company: "", companyUrl: "", buildNumber: null, companyId: "" } + defaultApp = { main: "Main", file: "MyApplication", path: "bin", preloader: "", swfVersion: 17, url: "", init: null } + defaultWindow = { width: 800, height: 600, parameters: "{}", background: 0xFFFFFF, fps: 30, hardware: true, display: 0, resizable: true, borderless: false, orientation: Orientation.AUTO, vsync: false, fullscreen: false, allowHighDPI: true, alwaysOnTop: false, antialiasing: 0, allowShaders: true, requireShaders: false, depthBuffer: true, stencilBuffer: true, colorDepth: 32, maximized: false, minimized: false, hidden: false } + + platformType = PlatformType.DESKTOP; + architectures = []; + + switch (target) { + + case AIR: + + if (targetFlags.exists ("ios") || targetFlags.exists ("android")) { + + platformType = PlatformType.MOBILE; + + defaultWindow.width = 0; + defaultWindow.height = 0; + + } else { + + platformType = PlatformType.DESKTOP; + + } + + architectures = []; + + case FLASH: + + platformType = PlatformType.WEB; + architectures = []; + + case HTML5, FIREFOX: + + platformType = PlatformType.WEB; + architectures = []; + + defaultWindow.width = 0; + defaultWindow.height = 0; + defaultWindow.fps = 60; + defaultWindow.allowHighDPI = false; + + case EMSCRIPTEN: + + platformType = PlatformType.WEB; + architectures = []; + + defaultWindow.fps = 60; + defaultWindow.allowHighDPI = false; + + case ANDROID, BLACKBERRY, IOS, TIZEN, WEBOS, TVOS: + + platformType = PlatformType.MOBILE; + + if (target == Platform.IOS) { + + architectures = [ Architecture.ARMV7, Architecture.ARM64 ]; + + } else if (target == Platform.ANDROID) { + + if (targetFlags.exists ("simulator") || targetFlags.exists ("emulator")) { + + architectures = [ Architecture.X86 ]; + + } else { + + architectures = [ Architecture.ARMV7 ]; + + } + + } else if (target == Platform.TVOS) { + + architectures = [ Architecture.ARM64 ]; + + } else { + + architectures = [ Architecture.ARMV6 ]; + + } + + defaultWindow.width = 0; + defaultWindow.height = 0; + defaultWindow.fullscreen = true; + defaultWindow.requireShaders = true; + + case WINDOWS: + + platformType = PlatformType.DESKTOP; + + if (targetFlags.exists ("uwp") || targetFlags.exists ("winjs")) { + + architectures = []; + + targetFlags.set ("uwp", ""); + targetFlags.set ("winjs", ""); + + defaultWindow.width = 0; + defaultWindow.height = 0; + defaultWindow.fps = 60; + + } else { + + switch (PlatformHelper.hostArchitecture) { + case ARMV6: architectures = [ ARMV6 ]; + case ARMV7: architectures = [ ARMV7 ]; + case X86: architectures = [ X86 ]; + case X64: architectures = [ X64 ]; + default: architectures = []; + } + + } + + defaultWindow.allowHighDPI = false; + + case MAC, LINUX: + + platformType = PlatformType.DESKTOP; + switch (PlatformHelper.hostArchitecture) { + case ARMV6: architectures = [ ARMV6 ]; + case ARMV7: architectures = [ ARMV7 ]; + case X86: architectures = [ X86 ]; + case X64: architectures = [ X64 ]; + default: architectures = []; + } + + defaultWindow.allowHighDPI = false; + + default: + + // TODO: Better handling of platform type for pluggable targets + + platformType = PlatformType.CONSOLE; + + defaultWindow.width = 0; + defaultWindow.height = 0; + defaultWindow.fps = 60; + defaultWindow.fullscreen = true; + + } + + defaultArchitectures = architectures.copy (); + + meta = ObjectHelper.copyFields (defaultMeta, {}); + app = ObjectHelper.copyFields (defaultApp, {}); + window = ObjectHelper.copyFields (defaultWindow, {}); + windows = [ window ]; + assets = new Array (); + + if (_userDefines != null) { + + defines = StringMapHelper.copy (_userDefines); + + } else { + + defines = new Map (); + + } + + dependencies = new Array (); + + if (_environment != null) { + + environment = _environment; + + } else { + + environment = Sys.environment (); + + } + + haxedefs = new Map (); + haxeflags = new Array (); + haxelibs = new Array (); + icons = new Array (); + javaPaths = new Array (); + languages = new Array (); + libraries = new Array (); + libraryHandlers = new Map (); + modules = new Map (); + ndlls = new Array (); + postBuildCallbacks = new Array (); + preBuildCallbacks = new Array (); + sources = new Array (); + samplePaths = new Array (); + splashScreens = new Array (); + targetHandlers = new Map (); + + } + + + public function clone ():Project { + + var project = new Project (); + + ObjectHelper.copyFields (app, project.app); + project.architectures = architectures.copy (); + project.assets = assets.copy (); + + for (i in 0...assets.length) { + + project.assets[i] = assets[i].clone (); + + } + + project.command = command; + project.config = config.clone (); + project.debug = debug; + + for (key in defines.keys ()) { + + project.defines.set (key, defines.get (key)); + + } + + for (dependency in dependencies) { + + project.dependencies.push (dependency.clone ()); + + } + + for (key in environment.keys ()) { + + project.environment.set (key, environment.get (key)); + + } + + for (key in haxedefs.keys ()) { + + project.haxedefs.set (key, haxedefs.get (key)); + + } + + project.haxeflags = haxeflags.copy (); + + for (haxelib in haxelibs) { + + project.haxelibs.push (haxelib.clone ()); + + } + + for (icon in icons) { + + project.icons.push (icon.clone ()); + + } + + project.javaPaths = javaPaths.copy (); + + if (keystore != null) { + + project.keystore = keystore.clone (); + + } + + project.languages = languages.copy (); + + for (library in libraries) { + + project.libraries.push (library.clone ()); + + } + + for (key in libraryHandlers.keys ()) { + + project.libraryHandlers.set (key, libraryHandlers.get (key)); + + } + + ObjectHelper.copyFields (meta, project.meta); + + for (key in modules.keys ()) { + + project.modules.set (key, modules.get (key).clone ()); + + } + + for (ndll in ndlls) { + + project.ndlls.push (ndll.clone ()); + + } + + project.platformType = platformType; + project.postBuildCallbacks = postBuildCallbacks.copy (); + project.preBuildCallbacks = preBuildCallbacks.copy (); + project.samplePaths = samplePaths.copy (); + project.sources = sources.copy (); + + for (splashScreen in splashScreens) { + + project.splashScreens.push (splashScreen.clone ()); + + } + + project.target = target; + + for (key in targetFlags.keys ()) { + + project.targetFlags.set (key, targetFlags.get (key)); + + } + + for (key in targetHandlers.keys ()) { + + project.targetHandlers.set (key, targetHandlers.get (key)); + + } + + project.templatePaths = templatePaths.copy (); + + for (i in 0...windows.length) { + + project.windows[i] = (ObjectHelper.copyFields (windows[i], {})); + + } + + return project; + + } + + + private function filter (text:String, include:Array = null, exclude:Array = null):Bool { + + if (include == null) { + + include = [ "*" ]; + + } + + if (exclude == null) { + + exclude = []; + + } + + for (filter in exclude) { + + if (filter != "") { + + filter = StringTools.replace (filter, ".", "\\."); + filter = StringTools.replace (filter, "*", ".*"); + + var regexp = new EReg ("^" + filter + "$", "i"); + + if (regexp.match (text)) { + + return false; + + } + + } + + } + + for (filter in include) { + + if (filter != "") { + + filter = StringTools.replace (filter, ".", "\\."); + filter = StringTools.replace (filter, "*", ".*"); + + var regexp = new EReg ("^" + filter, "i"); + + if (regexp.match (text)) { + + return true; + + } + + } + + } + + return false; + + } + + + public static function fromFile (projectFile:String, userDefines:Map = null, includePaths:Array = null):Project { + + var project:Project = null; + + var path = FileSystem.fullPath (Path.withoutDirectory (projectFile)); + var name = Path.withoutDirectory (Path.withoutExtension (projectFile)); + name = name.substr (0, 1).toUpperCase () + name.substr (1); + + var tempDirectory = PathHelper.getTemporaryDirectory (); + var classFile = PathHelper.combine (tempDirectory, name + ".hx"); + var nekoOutput = PathHelper.combine (tempDirectory, name + ".n"); + + FileHelper.copyFile (path, classFile); + + #if lime + var args = [ name, "-main", "lime.tools.Project", "-cp", tempDirectory, "-neko", nekoOutput, "-cp", PathHelper.combine (PathHelper.getHaxelib (new Haxelib ("hxp")), "src"), "-lib", "hxp" ]; + #else + var args = [ name, "--interp", "-main", "lime.tools.Project", "-cp", tempDirectory, "-cp", PathHelper.combine (PathHelper.getHaxelib (new Haxelib ("hxp")), "src") ]; + #end + var input = File.read (classFile, false); + var tag = "@:compiler("; + + try { + + while (true) { + + var line = input.readLine (); + + if (StringTools.startsWith (line, tag)) { + + args.push (line.substring (tag.length + 1, line.length - 2)); + + } + + } + + } catch (ex:Eof) {} + + input.close (); + + var cacheDryRun = ProcessHelper.dryRun; + ProcessHelper.dryRun = false; + + #if lime + ProcessHelper.runCommand ("", "haxe", args); + #end + + var inputFile = PathHelper.combine (tempDirectory, "input.dat"); + var outputFile = PathHelper.combine (tempDirectory, "output.dat"); + + var inputData = Serializer.run ({ + + command: Project._command, + name: name, + target: Project._target, + debug: Project._debug, + targetFlags: Project._targetFlags, + templatePaths: Project._templatePaths, + userDefines: Project._userDefines, + environment: Project._environment, + logVerbose: Log.verbose, + logEnableColor: Log.enableColor, + processDryRun: cacheDryRun, + haxelibDebug: HaxelibHelper.debug + + }); + + File.saveContent (inputFile, inputData); + + try { + + #if lime + ProcessHelper.runCommand ("", "neko", [ FileSystem.fullPath (nekoOutput), inputFile, outputFile ]); + #else + ProcessHelper.runCommand ("", "haxe", args.concat ([ "--", inputFile, outputFile ])); + #end + + } catch (e:Dynamic) { + + FileSystem.deleteFile (inputFile); + Sys.exit (1); + + } + + ProcessHelper.dryRun = cacheDryRun; + + var tPaths:Array = []; + + try { + + FileSystem.deleteFile (inputFile); + + var outputPath = PathHelper.combine (tempDirectory, "output.dat"); + + if (FileSystem.exists (outputPath)) { + + var output = File.getContent (outputPath); + var unserializer = new Unserializer (output); + unserializer.setResolver (cast { resolveEnum: Type.resolveEnum, resolveClass: resolveClass }); + project = unserializer.unserialize (); + + //Because the project file template paths need to take priority, + //Add them after loading template paths from haxelibs below + tPaths = project.templatePaths; + project.templatePaths = []; + + FileSystem.deleteFile (outputPath); + + } + + } catch (e:Dynamic) {} + + PathHelper.removeDirectory (tempDirectory); + + if (project != null) { + + for (key in project.environment.keys ()) { + + Sys.putEnv (key, project.environment[key]); + + } + + var defines = StringMapHelper.copy (userDefines); + StringMapHelper.copyKeys (project.defines, defines); + + processHaxelibs (project, defines); + + //Adding template paths from the Project file + project.templatePaths = ArrayHelper.concatUnique (project.templatePaths, tPaths, true); + } + + return project; + + } + + + public static function fromHaxelib (haxelib:Haxelib, userDefines:Map = null, clearCache:Bool = false):Project { + + if (haxelib.name == null || haxelib.name == "") { + + return null; + + } + + var path = PathHelper.getHaxelib (haxelib, false, clearCache); + + if (path == null || path == "") { + + return null; + + } + + //if (!userDefines.exists (haxelib.name)) { + // + //userDefines.set (haxelib.name, HaxelibHelper.getVersion (haxelib)); + // + //} + + return Project.fromPath (path, userDefines); + + } + + + public static function fromPath (path:String, userDefines:Map = null):Project { + + if (!FileSystem.exists (path) || !FileSystem.isDirectory (path)) { + + return null; + + } + + var files = [ "include.lime", "include.nmml", "include.xml" ]; + var projectFile = null; + + for (file in files) { + + if (projectFile == null && FileSystem.exists (PathHelper.combine (path, file))) { + + projectFile = PathHelper.combine (path, file); + + } + + } + + if (projectFile != null) { + + var project = new ProjectXMLParser (projectFile, userDefines); + + if (project.config.get ("project.rebuild.path") == null) { + + project.config.set ("project.rebuild.path", PathHelper.combine (path, "project")); + + } + + return project; + + } + + return null; + + } + + + private function getHaxelibVersion (haxelib:Haxelib):String { + + var version = haxelib.version; + + if (version == "" || version == null) { + + var haxelibPath = PathHelper.getHaxelib (haxelib); + var jsonPath = PathHelper.combine (haxelibPath, "haxelib.json"); + + try { + + if (FileSystem.exists (jsonPath)) { + + var json = Json.parse (File.getContent (jsonPath)); + version = json.version; + + } + + } catch (e:Dynamic) {} + + } + + return version; + + } + + + public function include (path:String):Void { + + // extend project file somehow? + + } + + + public function includeAssets (path:String, rename:String = null, include:Array = null, exclude:Array = null):Void { + + if (include == null) { + + include = [ "*" ]; + + } + + if (exclude == null) { + + exclude = []; + + } + + exclude = exclude.concat ([ ".*", "cvs", "thumbs.db", "desktop.ini", "*.hash" ]); + + if (path == "") { + + return; + + } + + var targetPath = ""; + + if (rename != null) { + + targetPath = rename; + + } else { + + targetPath = path; + + } + + if (!FileSystem.exists (path)) { + + Log.error ("Could not find asset path \"" + path + "\""); + return; + + } + + var files = FileSystem.readDirectory (path); + + if (targetPath != "") { + + targetPath += "/"; + + } + + for (file in files) { + + if (FileSystem.isDirectory (path + "/" + file)) { + + if (filter (file, [ "*" ], exclude)) { + + includeAssets (path + "/" + file, targetPath + file, include, exclude); + + } + + } else { + + if (filter (file, include, exclude)) { + + assets.push (new Asset (path + "/" + file, targetPath + file)); + + } + + } + + } + + } + + + // #if lime + + public function includeXML (xml:String):Void { + + var projectXML = new ProjectXMLParser (); + @:privateAccess projectXML.parseXML (new Fast (Xml.parse (xml).firstElement ()), ""); + merge (projectXML); + + } + + // #end + + + private static function initialize ():Void { + + if (!initialized) { + + if (_target == null) { + + _target = cast PlatformHelper.hostPlatform; + + } + + if (_targetFlags == null) { + + _targetFlags = new Map (); + + } + + if (_templatePaths == null) { + + _templatePaths = new Array (); + + } + + initialized = true; + + } + + } + + + public function merge (project:Project):Void { + + if (project != null) { + + ObjectHelper.copyUniqueFields (project.meta, meta, project.defaultMeta); + ObjectHelper.copyUniqueFields (project.app, app, project.defaultApp); + + for (i in 0...project.windows.length) { + + if (i < windows.length) { + + ObjectHelper.copyUniqueFields (project.windows[i], windows[i], project.defaultWindow); + + } else { + + windows.push (ObjectHelper.copyFields (project.windows[i], {})); + + } + + } + + StringMapHelper.copyUniqueKeys (project.defines, defines); + StringMapHelper.copyUniqueKeys (project.environment, environment); + StringMapHelper.copyUniqueKeys (project.haxedefs, haxedefs); + StringMapHelper.copyUniqueKeys (project.libraryHandlers, libraryHandlers); + StringMapHelper.copyUniqueKeys (project.targetHandlers, targetHandlers); + + config.merge (project.config); + + for (architecture in project.architectures) { + + if (defaultArchitectures.indexOf (architecture) == -1) { + + architectures.push (architecture); + + } + + } + + if (project.architectures.length > 0) { + + for (architecture in defaultArchitectures) { + + if (project.architectures.indexOf (architecture) == -1) { + + architectures.remove (architecture); + + } + + } + + } + + assets = ArrayHelper.concatUnique (assets, project.assets); + dependencies = ArrayHelper.concatUnique (dependencies, project.dependencies, true); + haxeflags = ArrayHelper.concatUnique (haxeflags, project.haxeflags); + haxelibs = ArrayHelper.concatUnique (haxelibs, project.haxelibs, true, "name"); + icons = ArrayHelper.concatUnique (icons, project.icons); + javaPaths = ArrayHelper.concatUnique (javaPaths, project.javaPaths, true); + + if (keystore == null) { + + keystore = project.keystore; + + } else { + + keystore.merge (project.keystore); + + } + + languages = ArrayHelper.concatUnique (languages, project.languages, true); + libraries = ArrayHelper.concatUnique (libraries, project.libraries, true); + + for (key in project.modules.keys ()) { + + if (modules.exists (key)) { + + modules.get (key).merge (project.modules.get (key)); + + } else { + + modules.set (key, project.modules.get (key)); + + } + + } + + ndlls = ArrayHelper.concatUnique (ndlls, project.ndlls); + postBuildCallbacks = postBuildCallbacks.concat (project.postBuildCallbacks); + preBuildCallbacks = preBuildCallbacks.concat (project.preBuildCallbacks); + samplePaths = ArrayHelper.concatUnique (samplePaths, project.samplePaths, true); + sources = ArrayHelper.concatUnique (sources, project.sources, true); + splashScreens = ArrayHelper.concatUnique (splashScreens, project.splashScreens); + templatePaths = ArrayHelper.concatUnique (templatePaths, project.templatePaths, true); + + } + + } + + + public function path (value:String):Void { + + if (host == Platform.WINDOWS) { + + setenv ("PATH", value + ";" + Sys.getEnv ("PATH")); + + } else { + + setenv ("PATH", value + ":" + Sys.getEnv ("PATH")); + + } + + } + + + // #if lime + + @:noCompletion private static function processHaxelibs (project:Project, userDefines:Map):Void { + + var haxelibs = project.haxelibs.copy (); + project.haxelibs = []; + + for (haxelib in haxelibs) { + + var validatePath = PathHelper.getHaxelib (haxelib, true); + project.haxelibs.push (haxelib); + + var includeProject = Project.fromHaxelib (haxelib, userDefines); + + if (includeProject != null) { + + for (ndll in includeProject.ndlls) { + + if (ndll.haxelib == null) { + + ndll.haxelib = haxelib; + + } + + } + + project.merge (includeProject); + + } + + } + + } + + + @:noCompletion private static function resolveClass (name:String):Class { + + var type = Type.resolveClass (name); + + if (type == null) { + + return Project; + + } else { + + return type; + + } + + } + + // #end + + + public function setenv (name:String, value:String):Void { + + if (value == null) { + + environment.remove (name); + value = ""; + + } + + if (name == "HAXELIB_PATH") { + + var currentPath = HaxelibHelper.getRepositoryPath (); + Sys.putEnv (name, value); + var newPath = HaxelibHelper.getRepositoryPath (true); + + if (currentPath != newPath) { + + var valid = try { (newPath != null && newPath != "" && FileSystem.exists (FileSystem.fullPath (newPath))); } catch (e:Dynamic) { false; } + + if (!valid) { + + Log.error ("The specified haxelib repository path \"" + value + "\" does not exist"); + + } else { + + needRerun = true; + + } + + } + + } else { + + Sys.putEnv (name, value); + + } + + if (value != "") { + + environment.set (name, value); + + } + + } + + + + + // Getters & Setters + + + + + private function get_host ():Platform { + + return cast PlatformHelper.hostPlatform; + + } + + + private function get_templateContext ():Dynamic { + + var context:Dynamic = {}; + + if (app == null) app = { }; + if (meta == null) meta = { }; + + if (window == null) { + + window = { }; + windows = [ window ]; + + } + + ObjectHelper.copyMissingFields (defaultApp, app); + ObjectHelper.copyMissingFields (defaultMeta, meta); + + for (item in windows) { + + ObjectHelper.copyMissingFields (defaultWindow, item); + + } + + //config.populate (); + + for (field in Reflect.fields (app)) { + + Reflect.setField (context, "APP_" + StringHelper.formatUppercaseVariable (field), Reflect.field (app, field)); + + } + + context.BUILD_DIR = app.path; + + for (key in environment.keys ()) { + + Reflect.setField (context, "ENV_" + key, environment.get (key)); + + } + + context.meta = meta; + + for (field in Reflect.fields (meta)) { + + Reflect.setField (context, "APP_" + StringHelper.formatUppercaseVariable (field), Reflect.field (meta, field)); + Reflect.setField (context, "META_" + StringHelper.formatUppercaseVariable (field), Reflect.field (meta, field)); + + } + + context.APP_PACKAGE = context.META_PACKAGE = meta.packageName; + + for (field in Reflect.fields (windows[0])) { + + Reflect.setField (context, "WIN_" + StringHelper.formatUppercaseVariable (field), Reflect.field (windows[0], field)); + Reflect.setField (context, "WINDOW_" + StringHelper.formatUppercaseVariable (field), Reflect.field (windows[0], field)); + + } + + if (windows[0].orientation == Orientation.LANDSCAPE || windows[0].orientation == Orientation.PORTRAIT) { + + context.WIN_ORIENTATION = Std.string (windows[0].orientation).toLowerCase (); + context.WINDOW_ORIENTATION = Std.string (windows[0].orientation).toLowerCase (); + + } else { + + context.WIN_ORIENTATION = ""; + context.WINDOW_ORIENTATION = ""; + + } + + context.windows = windows; + + for (i in 0...windows.length) { + + for (field in Reflect.fields (windows[i])) { + + Reflect.setField (context, "WINDOW_" + StringHelper.formatUppercaseVariable (field) + "_" + i, Reflect.field (windows[i], field)); + + } + + if (windows[i].orientation == Orientation.LANDSCAPE || windows[i].orientation == Orientation.PORTRAIT) { + + Reflect.setField (context, "WINDOW_ORIENTATION_" + i, Std.string (windows[i].orientation).toLowerCase ()); + + } else { + + Reflect.setField (context, "WINDOW_ORIENTATION_" + i, ""); + + } + + windows[i].title = meta.title; + + } + + for (haxeflag in haxeflags) { + + if (StringTools.startsWith (haxeflag, "-lib")) { + + Reflect.setField (context, "LIB_" + StringHelper.formatUppercaseVariable (haxeflag.substr (5)), "true"); + + } + + } + + context.assets = new Array (); + + for (asset in assets) { + + if (asset.type != AssetType.TEMPLATE) { + + var embeddedAsset:Dynamic = { }; + ObjectHelper.copyFields (asset, embeddedAsset); + + embeddedAsset.sourcePath = PathHelper.standardize (asset.sourcePath); + + if (asset.embed == null) { + + embeddedAsset.embed = (platformType == PlatformType.WEB || target == AIR); + + } + + embeddedAsset.type = Std.string (asset.type).toLowerCase (); + + #if (lime && lime_cffi && !macro) + if (asset.type == FONT) { + + try { + + var font = Font.fromFile (asset.sourcePath); + embeddedAsset.fontName = font.name; + + Log.info ("", " - \x1b[1mDetecting font name:\x1b[0m " + asset.sourcePath + " \x1b[3;37m->\x1b[0m \"" + font.name + "\""); + + } catch (e:Dynamic) {} + + } + #end + + context.assets.push (embeddedAsset); + + } + + } + + context.languages = (languages.length > 0) ? languages : null; + context.libraries = new Array (); + var embeddedLibraries = new Map (); + + for (library in libraries) { + + var embeddedLibrary:Dynamic = { }; + ObjectHelper.copyFields (library, embeddedLibrary); + context.libraries.push (embeddedLibrary); + embeddedLibraries[library.name] = embeddedLibrary; + + } + + for (asset in assets) { + + if (asset.library != null && !embeddedLibraries.exists (asset.library)) { + + var embeddedLibrary:Dynamic = { }; + embeddedLibrary.name = asset.library; + context.libraries.push (embeddedLibrary); + embeddedLibraries[asset.library] = embeddedLibrary; + + } + + } + + context.ndlls = new Array (); + + for (ndll in ndlls) { + + var templateNDLL:Dynamic = { }; + ObjectHelper.copyFields (ndll, templateNDLL); + templateNDLL.nameSafe = StringTools.replace (ndll.name, "-", "_"); + context.ndlls.push (templateNDLL); + + } + + //Reflect.setField (context, "ndlls", ndlls); + //Reflect.setField (context, "sslCaCert", sslCaCert); + context.sslCaCert = ""; + + var compilerFlags = []; + + for (haxelib in haxelibs) { + + var name = haxelib.name; + + // TODO: Handle real version when better/smarter haxelib available + var version = haxelib.version; + //var version = HaxelibHelper.getVersion (haxelib); + + if (version != null && version != "") { + + name += ":" + version; + + } + + // #if lime + + if (HaxelibHelper.pathOverrides.exists (name)) { + + var param = "-cp " + HaxelibHelper.pathOverrides.get (name); + compilerFlags.remove (param); + compilerFlags.push (param); + + } else { + + var cache = Log.verbose; + Log.verbose = HaxelibHelper.debug; + var output = ""; + + try { + + output = HaxelibHelper.runProcess ("", [ "path", name ], true, true, true); + + } catch (e:Dynamic) { } + + Log.verbose = cache; + + var split = output.split ("\n"); + var haxelibName = null; + + for (arg in split) { + + arg = StringTools.trim (arg); + + if (arg != "") { + + if (StringTools.startsWith (arg, "Error: ")) { + + Log.error (arg.substr (7)); + + } else if (!StringTools.startsWith (arg, "-")) { + + var path = PathHelper.standardize (arg); + + if (path != null && StringTools.trim (path) != "" && !StringTools.startsWith (StringTools.trim (path), "#")) { + + var param = "-cp " + path; + compilerFlags.remove (param); + compilerFlags.push (param); + + } + + var version = "0.0.0"; + var jsonPath = PathHelper.combine (path, "haxelib.json"); + + try { + + if (FileSystem.exists (jsonPath)) { + + var json = Json.parse (File.getContent (jsonPath)); + haxelibName = json.name; + compilerFlags = ArrayHelper.concatUnique (compilerFlags, [ "-D " + haxelibName + "=" + json.version ], true); + + } + + } catch (e:Dynamic) {} + + } else { + + if (StringTools.startsWith (arg, "-D ") && arg.indexOf ("=") == -1) { + + var name = arg.substr (3); + + if (name != haxelibName) { + + compilerFlags = ArrayHelper.concatUnique (compilerFlags, [ "-D " + name ], true); + + } + + /*var haxelib = new Haxelib (arg.substr (3)); + var path = PathHelper.getHaxelib (haxelib); + var version = getHaxelibVersion (haxelib); + + if (path != null) { + + CompatibilityHelper.patchProject (this, haxelib, version); + compilerFlags = ArrayHelper.concatUnique (compilerFlags, [ "-D " + haxelib.name + "=" + version ], true); + + }*/ + + } else if (!StringTools.startsWith (arg, "-L")) { + + compilerFlags = ArrayHelper.concatUnique (compilerFlags, [ arg ], true); + + } + + } + + } + + } + + } + + // #else + + // compilerFlags.push ("-lib " + name); + + // #end + + Reflect.setField (context, "LIB_" + StringHelper.formatUppercaseVariable (haxelib.name), true); + + if (name == "nme") { + + context.EMBED_ASSETS = false; + + } + + } + + for (source in sources) { + + if (source != null && StringTools.trim (source) != "") { + + compilerFlags.push ("-cp " + source); + + } + + } + + for (key in defines.keys ()) { + + var value = defines.get (key); + + if (value == null || value == "") { + + Reflect.setField (context, "SET_" + StringHelper.formatUppercaseVariable (key), true); + + } else { + + Reflect.setField (context, "SET_" + StringHelper.formatUppercaseVariable (key), value); + + } + + } + + for (key in haxedefs.keys ()) { + + var value = haxedefs.get (key); + + if (value == null || value == "") { + + compilerFlags.push ("-D " + key); + + Reflect.setField (context, "DEFINE_" + StringHelper.formatUppercaseVariable (key), true); + + } else { + + compilerFlags.push ("-D " + key + "=" + value); + + Reflect.setField (context, "DEFINE_" + StringHelper.formatUppercaseVariable (key), value); + + } + + } + + if (target != Platform.FLASH) { + + compilerFlags.push ("-D " + Std.string (target).toLowerCase ()); + + } + + compilerFlags.push ("-D " + Std.string (platformType).toLowerCase ()); + compilerFlags = compilerFlags.concat (haxeflags); + + if (compilerFlags.length == 0) { + + context.HAXE_FLAGS = ""; + + } else { + + context.HAXE_FLAGS = "\n" + compilerFlags.join ("\n"); + + } + + var main = app.main; + + if (main == null) { + + main = defaultApp.main; + + } + + var indexOfPeriod = main.lastIndexOf ("."); + + context.APP_MAIN_PACKAGE = main.substr (0, indexOfPeriod + 1); + context.APP_MAIN_CLASS = main.substr (indexOfPeriod + 1); + + var type = "release"; + + if (debug) { + + type = "debug"; + + } else if (targetFlags.exists ("final")) { + + type = "final"; + + } + + var hxml = Std.string (target).toLowerCase () + "/hxml/" + type + ".hxml"; + + for (templatePath in templatePaths) { + + var path = PathHelper.combine (templatePath, hxml); + + if (FileSystem.exists (path)) { + + context.HXML_PATH = path; + + } + + } + + context.RELEASE = (type == "release"); + context.DEBUG = debug; + context.FINAL = (type == "final"); + context.SWF_VERSION = app.swfVersion; + context.PRELOADER_NAME = app.preloader; + + if (keystore != null) { + + context.KEY_STORE = PathHelper.tryFullPath (keystore.path); + + if (keystore.password != null) { + + context.KEY_STORE_PASSWORD = keystore.password; + + } + + if (keystore.alias != null) { + + context.KEY_STORE_ALIAS = keystore.alias; + + } else if (keystore.path != null) { + + context.KEY_STORE_ALIAS = Path.withoutExtension (Path.withoutDirectory (keystore.path)); + + } + + if (keystore.aliasPassword != null) { + + context.KEY_STORE_ALIAS_PASSWORD = keystore.aliasPassword; + + } else if (keystore.password != null) { + + context.KEY_STORE_ALIAS_PASSWORD = keystore.password; + + } + + } + + context.config = config; + + return context; + + } + + + private function get_window ():WindowData { + + if (windows != null) { + + return windows[0]; + + } else { + + return window; + + } + + } + + + private function set_window (value:WindowData):WindowData { + + if (windows != null) { + + return windows[0] = window = value; + + } else { + + return window = value; + + } + + } + + +} diff --git a/src/lime/tools/ProjectHelper.hx b/src/lime/tools/ProjectHelper.hx new file mode 100644 index 000000000..4a63249e7 --- /dev/null +++ b/src/lime/tools/ProjectHelper.hx @@ -0,0 +1,231 @@ +package lime.tools; + + +import hxp.*; +import sys.io.File; +import sys.FileSystem; + +#if neko +import neko.Lib; +#elseif cpp +import cpp.Lib; +#end + + +class ProjectHelper { + + + //private static var doubleVarMatch = new EReg ("\\$\\${(.*?)}", ""); + private static var varMatch = new EReg ("{{(.*?)}}", ""); + + + public static function copyLibrary (project:Project, ndll:NDLL, directoryName:String, namePrefix:String, nameSuffix:String, targetDirectory:String, allowDebug:Bool = false, targetSuffix:String = null) { + + var path = PathHelper.getLibraryPath (ndll, directoryName, namePrefix, nameSuffix, allowDebug); + + if (FileSystem.exists (path)) { + + var targetPath = PathHelper.combine (targetDirectory, namePrefix + ndll.name); + + if (targetSuffix != null) { + + targetPath += targetSuffix; + + } else { + + targetPath += nameSuffix; + + } + + if (project.config.getBool ("tools.copy-ndlls")) { + + Log.info ("", " - \x1b[1mCopying library file:\x1b[0m " + path + " \x1b[3;37m->\x1b[0m " + targetPath); + + PathHelper.mkdir (targetDirectory); + + try { + + File.copy (path, targetPath); + + } catch (e:Dynamic) { + + Log.error ("Cannot copy to \"" + targetPath + "\", is the file in use?"); + + } + + } else { + + Log.info ("", " - \x1b[1mSkipping library file:\x1b[0m " + path + " \x1b[3;37m->\x1b[0m " + targetPath); + + } + + } else { + + Log.error ("Source path \"" + path + "\" does not exist"); + + } + + } + + + public static function getCurrentCommand ():String { + + var args = Sys.args (); + args.remove ("-watch"); + + if (HaxelibHelper.pathOverrides.exists ("lime-tools")) { + + var tools = HaxelibHelper.pathOverrides.get ("lime-tools"); + + return "neko " + tools + "/tools.n " + args.join (" "); + + } else { + + args.pop (); + + return "lime " + args.join (" "); + + } + + } + + + public static function recursiveSmartCopyTemplate (project:Project, source:String, destination:String, context:Dynamic = null, process:Bool = true, warnIfNotFound:Bool = true) { + + var destinations = []; + var paths = PathHelper.findTemplateRecursive (project.templatePaths, source, warnIfNotFound, destinations); + + if (paths != null) { + + PathHelper.mkdir (destination); + var itemDestination; + + for (i in 0...paths.length) { + + itemDestination = PathHelper.combine (destination, ProjectHelper.substitutePath (project, destinations[i])); + FileHelper.copyFile (paths[i], itemDestination, context, process); + + } + + } + + } + + + public static function replaceVariable (project:Project, string:String):String { + + if (string.substr (0, 8) == "haxelib:") { + + var path = HaxelibHelper.getPath (new Haxelib (string.substr (8)), true); + return PathHelper.standardize (path); + + } else if (project.defines.exists (string)) { + + return project.defines.get (string); + + } else if (project.environment != null && project.environment.exists (string)) { + + return project.environment.get (string); + + } else { + + var substring = StringTools.replace (string, " ", ""); + var index, value; + + if (substring.indexOf ("==") > -1) { + + index = substring.indexOf ("=="); + value = ProjectHelper.replaceVariable (project, substring.substr (0, index)); + + return Std.string (value == substring.substr (index + 2)); + + } else if (substring.indexOf ("!=") > -1) { + + index = substring.indexOf ("!="); + value = ProjectHelper.replaceVariable (project, substring.substr (0, index)); + + return Std.string (value != substring.substr (index + 2)); + + } else if (substring.indexOf ("<=") > -1) { + + index = substring.indexOf ("<="); + value = ProjectHelper.replaceVariable (project, substring.substr (0, index)); + + return Std.string (value <= substring.substr (index + 2)); + + } else if (substring.indexOf ("<") > -1) { + + index = substring.indexOf ("<"); + value = ProjectHelper.replaceVariable (project, substring.substr (0, index)); + + return Std.string (value < substring.substr (index + 1)); + + } else if (substring.indexOf (">=") > -1) { + + index = substring.indexOf (">="); + value = ProjectHelper.replaceVariable (project, substring.substr (0, index)); + + return Std.string (value >= substring.substr (index + 2)); + + } else if (substring.indexOf (">") > -1) { + + index = substring.indexOf (">"); + value = ProjectHelper.replaceVariable (project, substring.substr (0, index)); + + return Std.string (value > substring.substr (index + 1)); + + } else if (substring.indexOf (".") > -1) { + + var index = substring.indexOf ("."); + var fieldName = substring.substr (0, index); + var subField = substring.substr (index + 1); + + if (Reflect.hasField (project, fieldName)) { + + var field = Reflect.field (project, fieldName); + + if (Reflect.hasField (field, subField)) { + + return Std.string (Reflect.field (field, subField)); + + } + + } + + } #if sys else if (substring == "projectDirectory") { + + // TODO: Better handling if CWD has changed? + + return Std.string (Sys.getCwd ()); + + } #end + + } + + return string; + + } + + + public static function substitutePath (project:Project, path:String):String { + + var newString = path; + + // while (doubleVarMatch.match (newString)) { + + // newString = doubleVarMatch.matchedLeft () + "${" + ProjectHelper.replaceVariable (this, doubleVarMatch.matched (1)) + "}" + doubleVarMatch.matchedRight (); + + // } + + while (varMatch.match (newString)) { + + newString = varMatch.matchedLeft () + ProjectHelper.replaceVariable (project, varMatch.matched (1)) + varMatch.matchedRight (); + + } + + return newString; + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/ProjectXMLParser.hx b/src/lime/tools/ProjectXMLParser.hx new file mode 100644 index 000000000..ba95eee93 --- /dev/null +++ b/src/lime/tools/ProjectXMLParser.hx @@ -0,0 +1,2301 @@ +package lime.tools; + + +import haxe.io.Path; +import haxe.xml.Fast; +import hxp.*; +import lime.tools.CommandHelper; +import lime.tools.ModuleHelper; +import lime.tools.Asset; +import lime.tools.AssetType; +import lime.tools.Dependency; +import hxp.Haxelib; +import lime.tools.Project; +#if lime +import lime.utils.AssetManifest; +#end +import sys.io.File; +import sys.FileSystem; + + +class ProjectXMLParser extends Project { + + + public var includePaths:Array; + + private static var doubleVarMatch = new EReg ("\\$\\${(.*?)}", ""); + private static var varMatch = new EReg ("\\${(.*?)}", ""); + + + public function new (path:String = "", defines:Map = null, includePaths:Array = null, useExtensionPath:Bool = false) { + + super (); + + if (defines != null) { + + this.defines = StringMapHelper.copy (defines); + + } + + if (includePaths != null) { + + this.includePaths = includePaths; + + } else { + + this.includePaths = new Array (); + + } + + initialize (); + + if (path != "") { + + process (path, useExtensionPath); + + } + + } + + + private function initialize ():Void { + + switch (platformType) { + + case MOBILE: + + defines.set ("platformType", "mobile"); + defines.set ("mobile", "1"); + + case DESKTOP: + + defines.set ("platformType", "desktop"); + defines.set ("desktop", "1"); + + case WEB: + + defines.set ("platformType", "web"); + defines.set ("web", "1"); + + case CONSOLE: + + defines.set ("platformType", "console"); + defines.set ("console", "1"); + + } + + if (targetFlags.exists ("neko")) { + + defines.set ("targetType", "neko"); + defines.set ("native", "1"); + defines.set ("neko", "1"); + + } else if (targetFlags.exists ("hl")) { + + defines.set ("targetType", "hl"); + defines.set ("native", "1"); + defines.set ("hl", "1"); + + } else if (targetFlags.exists ("java")) { + + defines.set ("targetType", "java"); + defines.set ("native", "1"); + defines.set ("java", "1"); + + } else if (targetFlags.exists ("nodejs")) { + + defines.set ("targetType", "nodejs"); + defines.set ("native", "1"); + defines.set ("nodejs", "1"); + + } else if (targetFlags.exists ("cs")) { + + defines.set ("targetType", "cs"); + defines.set ("native", "1"); + defines.set ("cs", "1"); + + } else if (target == Platform.FIREFOX) { + + defines.set ("targetType", "js"); + defines.set ("html5", "1"); + + } else if (target == Platform.AIR) { + + defines.set ("targetType", "swf"); + defines.set ("flash", "1"); + if (targetFlags.exists("ios")) defines.set ("ios", "1"); + if (targetFlags.exists("android")) defines.set ("android", "1"); + + } else if (target == Platform.WINDOWS && (targetFlags.exists ("uwp") || targetFlags.exists ("winjs"))) { + + targetFlags.set ("uwp", ""); + targetFlags.set ("winjs", ""); + + defines.set ("targetType", "js"); + defines.set ("html5", "1"); + defines.set ("uwp", "1"); + defines.set ("winjs", "1"); + + } else if (platformType == DESKTOP && target != cast PlatformHelper.hostPlatform) { + + defines.set ("native", "1"); + + if (target == Platform.WINDOWS) { + + defines.set ("targetType", "cpp"); + defines.set ("cpp", "1"); + defines.set ("mingw", "1"); + + } else { + + defines.set ("targetType", "neko"); + defines.set ("neko", "1"); + + } + + } else if (targetFlags.exists ("cpp") || ((platformType != PlatformType.WEB) && !targetFlags.exists ("html5")) || target == Platform.EMSCRIPTEN) { + + defines.set ("targetType", "cpp"); + defines.set ("native", "1"); + defines.set ("cpp", "1"); + + } else if (target == Platform.FLASH) { + + defines.set ("targetType", "swf"); + + } + + if (debug) { + + defines.set ("buildType", "debug"); + defines.set ("debug", "1"); + + } else if (targetFlags.exists ("final")) { + + defines.set ("buildType", "final"); + defines.set ("final", "1"); + + } else { + + defines.set ("buildType", "release"); + defines.set ("release", "1"); + + } + + if (targetFlags.exists ("static")) { + + defines.set ("static_link", "1"); + + } + + if (defines.exists ("SWF_PLAYER")) { + + environment.set ("SWF_PLAYER", defines.get ("SWF_PLAYER")); + + } + + defines.set (Std.string (target).toLowerCase (), "1"); + defines.set ("target", Std.string (target).toLowerCase ()); + defines.set ("platform", defines.get ("target")); + + switch (PlatformHelper.hostPlatform) { + + case WINDOWS: defines.set ("host", "windows"); + case MAC: defines.set ("host", "mac"); + case LINUX: defines.set ("host", "linux"); + default: defines.set ("host", "unknown"); + + } + + #if lime + defines.set ("lime-tools", "1"); + #end + + defines.set ("hxp", "1"); // TODO: Version? + + } + + + private function isValidElement (element:Fast, section:String):Bool { + + if (element.x.get ("if") != null) { + + var value = element.x.get ("if"); + var optionalDefines = value.split ("||"); + var matchOptional = false; + + for (optional in optionalDefines) { + + optional = substitute (optional); + var requiredDefines = optional.split (" "); + var matchRequired = true; + + for (required in requiredDefines) { + + required = substitute (required); + var check = StringTools.trim (required); + + if (check == "false") { + + matchRequired = false; + + } else if (check != "" && check != "true" && !defines.exists (check) && (environment == null || !environment.exists (check)) && check != command) { + + matchRequired = false; + + } + + } + + if (matchRequired) { + + matchOptional = true; + + } + + } + + if (optionalDefines.length > 0 && !matchOptional) { + + return false; + + } + + } + + if (element.has.unless) { + + var value = substitute (element.att.unless); + var optionalDefines = value.split ("||"); + var matchOptional = false; + + for (optional in optionalDefines) { + + optional = substitute (optional); + var requiredDefines = optional.split (" "); + var matchRequired = true; + + for (required in requiredDefines) { + + required = substitute (required); + var check = StringTools.trim (required); + + if (check == "false") { + + matchRequired = false; + + } else if (check != "" && check != "true" && !defines.exists (check) && (environment == null || !environment.exists (check)) && check != command) { + + matchRequired = false; + + } + + } + + if (matchRequired) { + + matchOptional = true; + + } + + } + + if (optionalDefines.length > 0 && matchOptional) { + + return false; + + } + + } + + if (section != "") { + + if (element.name != "section") { + + return false; + + } + + if (!element.has.id) { + + return false; + + } + + if (substitute (element.att.id) != section) { + + return false; + + } + + } + + return true; + + } + + + private function findIncludeFile (base:String):String { + + if (base == "") { + + return ""; + + } + + if (base.substr (0, 1) != "/" && base.substr (0, 1) != "\\" && base.substr (1, 1) != ":" && base.substr (0, 1) != "." && !FileSystem.exists (base)) { + + for (path in includePaths) { + + var includePath = path + "/" + base; + + if (FileSystem.exists (includePath)) { + + if (FileSystem.exists (includePath + "/include.lime")) { + + return includePath + "/include.lime"; + + } else if (FileSystem.exists (includePath + "/include.nmml")) { + + return includePath + "/include.nmml"; + + } else if (FileSystem.exists (includePath + "/include.xml")) { + + return includePath + "/include.xml"; + + } else { + + return includePath; + + } + + } + + } + + } else { + + if (base.substr ( -1, 1) == "/") { + + base = base.substr (0, base.length - 1); + + } else if (base.substr ( -1, 1) == "\\") { + + base = base.substring (0, base.length - 1); + + } + + if (FileSystem.exists (base)) { + + if (FileSystem.exists (base + "/include.lime")) { + + return base + "/include.lime"; + + } else if (FileSystem.exists (base + "/include.nmml")) { + + return base + "/include.nmml"; + + } else if (FileSystem.exists (base + "/include.xml")) { + + return base + "/include.xml"; + + } else { + + return base; + + } + + } + + } + + return ""; + + } + + + private function formatAttributeName (name:String):String { + + var segments = name.toLowerCase ().split ("-"); + + for (i in 1...segments.length) { + + segments[i] = segments[i].substr (0, 1).toUpperCase () + segments[i].substr (1); + + } + + return segments.join (""); + + } + + + public static function fromFile (path:String, defines:Map = null, includePaths:Array = null, useExtensionPath:Bool = false):ProjectXMLParser { + + if (path == null) return null; + + if (FileSystem.exists (path)) { + + return new ProjectXMLParser (path, defines, includePaths, useExtensionPath); + + } + + return null; + + } + + + private function parseAppElement (element:Fast, extensionPath:String):Void { + + for (attribute in element.x.attributes ()) { + + switch (attribute) { + + case "path": + + app.path = PathHelper.combine (extensionPath, substitute (element.att.path)); + + case "min-swf-version": + + var version = Std.parseFloat (substitute (element.att.resolve ("min-swf-version"))); + + if (version > app.swfVersion) { + + app.swfVersion = version; + + } + + case "swf-version": + + app.swfVersion = Std.parseFloat (substitute (element.att.resolve ("swf-version"))); + + case "preloader": + + app.preloader = substitute (element.att.preloader); + + default: + + // if we are happy with this spec, we can tighten up this parsing a bit, later + + var name = formatAttributeName (attribute); + var value = substitute (element.att.resolve (attribute)); + + if (attribute == "package") { + + name = "packageName"; + + } + + if (Reflect.hasField (app, name)) { + + Reflect.setField (app, name, value); + + } else if (Reflect.hasField (meta, name)) { + + Reflect.setField (meta, name, value); + + } + + } + + } + + } + + + private function parseAssetsElement (element:Fast, basePath:String = "", isTemplate:Bool = false):Void { + + var path = ""; + var embed:Null = null; + var library = null; + var targetPath = ""; + var glyphs = null; + var type = null; + + if (element.has.path) { + + path = PathHelper.combine (basePath, substitute (element.att.path)); + + } + + if (element.has.embed) { + + embed = parseBool (element.att.embed); + + } + + if (element.has.rename) { + + targetPath = substitute (element.att.rename); + + } else if (element.has.path) { + + targetPath = substitute (element.att.path); + + } + + if (element.has.library) { + + library = substitute (element.att.library); + + } + + if (element.has.glyphs) { + + glyphs = substitute (element.att.glyphs); + + } + + if (isTemplate) { + + type = AssetType.TEMPLATE; + + } else if (element.has.type) { + + var typeName = substitute (element.att.type); + + if (Reflect.hasField (AssetType, typeName.toUpperCase ())) { + + type = Reflect.field (AssetType, typeName.toUpperCase ()); + + } else if (typeName == "bytes") { + + type = AssetType.BINARY; + + } else { + + Log.warn ("Ignoring unknown asset type \"" + typeName + "\""); + + } + + } + + if (path == "" && (element.has.include || element.has.exclude || type != null )) { + + Log.error ("In order to use 'include' or 'exclude' on nodes, you must specify also specify a 'path' attribute"); + return; + + } else if (!element.elements.hasNext ()) { + + // Empty element + + if (path == "") { + + return; + + } + + if (!FileSystem.exists (path)) { + + Log.error ("Could not find asset path \"" + path + "\""); + return; + + } + + if (!FileSystem.isDirectory (path)) { + + var asset = new Asset (path, targetPath, type, embed); + asset.library = library; + + if (element.has.id) { + + asset.id = substitute (element.att.id); + + } + + if (glyphs != null) { + + asset.glyphs = glyphs; + + } + + assets.push (asset); + + } else if (Path.extension (path) == "bundle") { + + parseAssetsElementLibrary (path, targetPath, null, null, type, embed, library, glyphs, true); + + } else { + + var exclude = ".*|cvs|thumbs.db|desktop.ini|*.fla|*.hash"; + var include = ""; + + if (element.has.exclude) { + + exclude += "|" + substitute (element.att.exclude); + + } + + if (element.has.include) { + + include = substitute (element.att.include); + + } else { + + //if (type == null) { + + include = "*"; + + /*} else { + + switch (type) { + + case IMAGE: + + include = "*.jpg|*.jpeg|*.png|*.gif"; + + case SOUND: + + include = "*.wav|*.ogg"; + + case MUSIC: + + include = "*.mp2|*.mp3|*.ogg"; + + case FONT: + + include = "*.otf|*.ttf"; + + case TEMPLATE: + + include = "*"; + + default: + + include = "*"; + + } + + }*/ + + } + + parseAssetsElementDirectory (path, targetPath, include, exclude, type, embed, library, glyphs, true); + + } + + } else { + + if (path != "") { + + path += "/"; + + } + + if (targetPath != "") { + + targetPath += "/"; + + } + + for (childElement in element.elements) { + + var isValid = isValidElement (childElement, ""); + + if (isValid) { + + var childPath = substitute (childElement.has.name ? childElement.att.name : childElement.att.path); + var childTargetPath = childPath; + var childEmbed:Null = embed; + var childLibrary = library; + var childType = type; + var childGlyphs = glyphs; + + if (childElement.has.rename) { + + childTargetPath = substitute (childElement.att.rename); + + } + + if (childElement.has.embed) { + + childEmbed = parseBool (childElement.att.embed); + + } + + if (childElement.has.library) { + + childLibrary = substitute (childElement.att.library); + + } + + if (childElement.has.glyphs) { + + childGlyphs = substitute (childElement.att.glyphs); + + } + + switch (childElement.name) { + + case "image", "sound", "music", "font", "template": + + childType = Reflect.field (AssetType, childElement.name.toUpperCase ()); + + case "library", "manifest": + + childType = AssetType.MANIFEST; + + default: + + if (childElement.has.type) { + + childType = Reflect.field (AssetType, substitute (childElement.att.type).toUpperCase ()); + + } + + } + + var id = ""; + + if (childElement.has.id) { + + id = substitute (childElement.att.id); + + } + else if (childElement.has.name) { + + id = substitute (childElement.att.name); + + } + + var asset = new Asset (path + childPath, targetPath + childTargetPath, childType, childEmbed); + asset.library = childLibrary; + asset.id = id; + + if (childGlyphs != null) { + + asset.glyphs = childGlyphs; + + } + + assets.push (asset); + + } + + } + + } + + } + + + private function parseAssetsElementDirectory (path:String, targetPath:String, include:String, exclude:String, type:AssetType, embed:Null, library:String, glyphs:String, recursive:Bool):Void { + + var files = FileSystem.readDirectory (path); + + if (targetPath != "") { + + targetPath += "/"; + + } + + for (file in files) { + + if (FileSystem.isDirectory (path + "/" + file)) { + + if (Path.extension (file) == "bundle") { + + parseAssetsElementLibrary (path + "/" + file, targetPath + file, include, exclude, type, embed, library, glyphs, true); + + } else if (recursive) { + + if (filter (file, [ "*" ], exclude.split ("|"))) { + + parseAssetsElementDirectory (path + "/" + file, targetPath + file, include, exclude, type, embed, library, glyphs, true); + + } + + } + + } else { + + if (filter (file, include.split ("|"), exclude.split ("|"))) { + + var asset = new Asset (path + "/" + file, targetPath + file, type, embed); + asset.library = library; + + if (glyphs != null) { + + asset.glyphs = glyphs; + + } + + assets.push (asset); + + } + + } + + } + + } + + + private function parseAssetsElementLibrary (path:String, targetPath:String, include:String, exclude:String, type:AssetType, embed:Null, library:String, glyphs:String, recursive:Bool):Void { + + var includePath = findIncludeFile (path); + + if (includePath != null && includePath != "" && FileSystem.exists (includePath) && !FileSystem.isDirectory (includePath)) { + + var includeProject = new ProjectXMLParser (includePath, defines); + merge (includeProject); + + } + + var processedLibrary = false; + var jsonPath = PathHelper.combine (path, "library.json"); + + if (FileSystem.exists (jsonPath)) { + + #if lime + try { + + var manifest = AssetManifest.fromFile (jsonPath); + + if (manifest != null) { + + library = targetPath; + manifest.rootPath = targetPath; + + var asset = new Asset ("", PathHelper.combine (targetPath, "library.json"), AssetType.MANIFEST); + asset.id = "libraries/" + library + ".json"; + asset.library = library; + asset.data = manifest.serialize (); + asset.embed = embed; + assets.push (asset); + + for (manifestAsset in manifest.assets) { + + if (Reflect.hasField (manifestAsset, "path")) { + + var asset = new Asset (PathHelper.combine (path, manifestAsset.path), PathHelper.combine (targetPath, manifestAsset.path), type, embed); + asset.id = manifestAsset.id; + asset.library = library; + asset.embed = embed; + assets.push (asset); + + } + + } + + processedLibrary = true; + + } + + } catch (e:Dynamic) {} + #end + + } + + if (!processedLibrary) { + + parseAssetsElementDirectory (path, targetPath, include, exclude, type, embed, library, glyphs, true); + + } + + } + + + private function parseBool (attribute:String):Bool { + + return substitute (attribute) == "true"; + + } + + + private function parseCommandElement (element:Fast, commandList:Array):Void { + + var command:CLICommand = null; + + if (element.has.haxe) { + + command = CommandHelper.interpretHaxe (substitute (element.att.haxe)); + + } + + if (element.has.open) { + + command = CommandHelper.openFile (substitute (element.att.open)); + + } + + if (element.has.command) { + + command = CommandHelper.fromSingleString (substitute (element.att.command)); + + } + + if (element.has.cmd) { + + command = CommandHelper.fromSingleString (substitute (element.att.cmd)); + + } + + if (command != null) { + + for (arg in element.elements) { + + if (arg.name == "arg") { + + command.args.push (arg.innerData); + + } + + } + + commandList.push (command); + + } + + } + + + private function parseMetaElement (element:Fast):Void { + + for (attribute in element.x.attributes ()) { + + switch (attribute) { + + case "title", "description", "package", "version", "company", "company-id", "build-number", "company-url": + + var value = substitute (element.att.resolve (attribute)); + + defines.set ("APP_" + StringTools.replace (attribute, "-", "_").toUpperCase (), value); + + var name = formatAttributeName (attribute); + + if (attribute == "package") { + + name = "packageName"; + + } + + if (Reflect.hasField (meta, name)) { + + Reflect.setField (meta, name, value); + + } + + } + + } + + } + + + private function parseModuleElement (element:Fast, basePath:String = "", moduleData:ModuleData = null):Void { + + var topLevel = (moduleData == null); + + var exclude = ""; + var include = "*"; + + if (element.has.include) { + + include = substitute (element.att.include); + + } + + if (element.has.exclude) { + + exclude = substitute (element.att.exclude); + + } + + if (moduleData == null) { + + var name = substitute (element.att.name); + + if (modules.exists (name)) { + + moduleData = modules.get (name); + + } else { + + moduleData = new ModuleData (name); + modules.set (name, moduleData); + + } + + } + + switch (element.name) { + + case "module" | "source": + + var sourceAttribute = (element.name == "module" ? "source" : "path"); + + if (element.has.resolve (sourceAttribute)) { + + var source = PathHelper.combine (basePath, substitute (element.att.resolve (sourceAttribute))); + var packageName = ""; + + if (element.has.resolve ("package")) { + + packageName = element.att.resolve ("package"); + + } + + ModuleHelper.addModuleSource (source, moduleData, include.split ("|"), exclude.split ("|"), packageName); + + } + + case "class": + + if (element.has.remove) { + + moduleData.classNames.remove (substitute (element.att.remove)); + + } else { + + moduleData.classNames.push (substitute (element.att.name)); + + } + + case "haxedef": + + var value = substitute (element.att.name); + + if (element.has.value) { + + value += "=" + substitute (element.att.value); + + } + + moduleData.haxeflags.push ("-D " + value); + + case "haxeflag": + + var flag = substitute (element.att.name); + + if (element.has.value) { + + flag += " " + substitute (element.att.value); + + } + + moduleData.haxeflags.push (substitute (flag)); + + case "include": + + moduleData.includeTypes.push (substitute (element.att.type)); + + case "exclude": + + moduleData.excludeTypes.push (substitute (element.att.type)); + + } + + if (topLevel) { + + for (childElement in element.elements) { + + if (isValidElement (childElement, "")) { + + parseModuleElement (childElement, basePath, moduleData); + + } + + } + + } + + } + + + private function parseOutputElement (element:Fast, extensionPath:String):Void { + + if (element.has.name) { + + app.file = substitute (element.att.name); + + } + + if (element.has.path) { + + app.path = PathHelper.combine (extensionPath, substitute (element.att.path)); + + } + + if (element.has.resolve ("swf-version")) { + + app.swfVersion = Std.parseFloat (substitute (element.att.resolve ("swf-version"))); + + } + + } + + + private function parseXML (xml:Fast, section:String, extensionPath:String = ""):Void { + + for (element in xml.elements) { + + var isValid = isValidElement (element, section); + if (isValid) { + + switch (element.name) { + + case "set": + + var name = element.att.name; + var value = ""; + + if (element.has.value) { + + value = substitute (element.att.value); + + } + + switch (name) { + + case "BUILD_DIR": app.path = value; + case "SWF_VERSION": app.swfVersion = Std.parseFloat (value); + case "PRERENDERED_ICON": config.set ("ios.prerenderedIcon", value); + case "ANDROID_INSTALL_LOCATION": config.set ("android.install-location", value); + + } + + defines.set (name, value); + environment.set (name, value); + + case "unset": + + defines.remove (element.att.name); + environment.remove (element.att.name); + + case "define": + + var name = element.att.name; + var value = ""; + + if (element.has.value) { + + value = substitute (element.att.value); + + } + + defines.set (name, value); + haxedefs.set (name, value); + environment.set (name, value); + + case "setenv": + + var value = ""; + + if (element.has.value) { + + value = substitute (element.att.value); + + } else { + + value = "1"; + + } + + var name = substitute (element.att.name); + + defines.set (name, value); + environment.set (name, value); + setenv (name, value); + + if (needRerun) return; + + case "error": + + Log.error (substitute (element.att.value)); + + case "echo": + + Log.println (substitute (element.att.value)); + + case "log": + + var verbose = ""; + + if (element.has.verbose) { + + verbose = substitute (element.att.verbose); + + } + + if (element.has.error) { + + Log.error (substitute (element.att.error), verbose); + + } else if (element.has.warn) { + + Log.warn (substitute (element.att.warn), verbose); + + } else if (element.has.info) { + + Log.info (substitute (element.att.info), verbose); + + } else if (element.has.value) { + + Log.info (substitute (element.att.value), verbose); + + } else if (verbose != "") { + + Log.info ("", verbose); + + } + + case "path": + + var value = ""; + + if (element.has.value) { + + value = substitute (element.att.value); + + } else { + + value = substitute (element.att.name); + + } + + path (value); + + case "include": + + var path = ""; + var addSourcePath = true; + var haxelib = null; + + if (element.has.haxelib) { + + haxelib = new Haxelib (substitute (element.att.haxelib)); + path = findIncludeFile (HaxelibHelper.getPath (haxelib, true)); + addSourcePath = false; + + } else if (element.has.path) { + + var subPath = substitute (element.att.path); + if (subPath == "") subPath = element.att.path; + + path = findIncludeFile (PathHelper.combine (extensionPath, subPath)); + + } else { + + path = findIncludeFile (PathHelper.combine (extensionPath, substitute (element.att.name))); + + } + + if (path != null && path != "" && FileSystem.exists (path) && !FileSystem.isDirectory (path)) { + + var includeProject = new ProjectXMLParser (path, defines); + + if (includeProject != null && haxelib != null) { + + for (ndll in includeProject.ndlls) { + + if (ndll.haxelib == null) { + + ndll.haxelib = haxelib; + + } + + } + + } + + if (addSourcePath) { + + var dir = Path.directory (path); + + if (dir != "") { + + includeProject.sources.unshift (dir); + + } + + } + + merge (includeProject); + + } else if (!element.has.noerror) { + + if (path == "" || FileSystem.isDirectory (path)) { + + var errorPath = ""; + + if (element.has.path) { + + errorPath = element.att.path; + + } else if (element.has.name) { + + errorPath = element.att.name; + + } else { + + errorPath = Std.string (element); + + } + + Log.error ("\"" + errorPath + "\" does not appear to be a valid path"); + + } else { + + Log.error ("Could not find include file \"" + path + "\""); + + } + + } + + case "meta": + + parseMetaElement (element); + + case "app": + + parseAppElement (element, extensionPath); + + case "java": + + javaPaths.push (PathHelper.combine (extensionPath, substitute (element.att.path))); + + case "language": + + languages.push (element.att.name); + + case "haxelib": + + if (element.has.repository) { + + setenv ("HAXELIB_PATH", PathHelper.combine (Sys.getCwd (), element.att.repository)); + if (needRerun) return; + continue; + + } + + var name = substitute (element.att.name); + var version = ""; + var optional = false; + var path = null; + + if (element.has.version) { + + version = substitute (element.att.version); + + } + + if (element.has.optional) { + + optional = parseBool (element.att.optional); + + } + + if (element.has.path) { + + path = PathHelper.combine (extensionPath, substitute (element.att.path)); + + } + + var haxelib = new Haxelib (name, version); + + if (version != "" && defines.exists (name) && !haxelib.versionMatches (defines.get (name))) { + + Log.warn ("Ignoring requested haxelib \"" + name + "\" version \"" + version + "\" (version \"" + defines.get (name) + "\" was already included)"); + continue; + + } + + if (path == null) { + + if (defines.exists ("setup")) { + + path = HaxelibHelper.getPath (haxelib); + + } else { + + path = HaxelibHelper.getPath (haxelib, !optional); + + if (optional && path == "") { + + continue; + + } + + } + + } else { + + path = PathHelper.tryFullPath (PathHelper.combine (extensionPath, path)); + + if (version != "") { + + HaxelibHelper.pathOverrides.set (name + ":" + version, path); + + } else { + + HaxelibHelper.pathOverrides.set (name, path); + + } + + } + + if (!defines.exists (haxelib.name)) { + + defines.set (haxelib.name, Std.string (HaxelibHelper.getVersion (haxelib))); + + } + + haxelibs.push (haxelib); + + var includeProject = Project.fromHaxelib (haxelib, defines); + + if (includeProject != null) { + + for (ndll in includeProject.ndlls) { + + if (ndll.haxelib == null) { + + ndll.haxelib = haxelib; + + } + + } + + merge (includeProject); + + } + + case "ndll": + + var name = substitute (element.att.name); + var haxelib = null; + var type = NDLLType.AUTO; + var registerStatics = true; + var subdirectory = null; + + if (element.has.haxelib) { + + haxelib = new Haxelib (substitute (element.att.haxelib)); + + } + + if (element.has.dir) { + + subdirectory = substitute (element.att.dir); + + } + + if (haxelib == null && (name == "std" || name == "regexp" || name == "zlib")) { + + haxelib = new Haxelib (config.getString ("cpp.buildLibrary", "hxcpp")); + + } + + if (element.has.type) { + + type = Reflect.field (NDLLType, substitute (element.att.type).toUpperCase ()); + + } + + if (element.has.register) { + + registerStatics = parseBool (element.att.register); + + } + + var ndll = new NDLL (name, haxelib, type, registerStatics); + ndll.extensionPath = extensionPath; + ndll.subdirectory = subdirectory; + + ndlls.push (ndll); + + case "architecture": + + if (element.has.name) { + + var name = substitute (element.att.name); + + if (Reflect.hasField (Architecture, name.toUpperCase ())) { + + ArrayHelper.addUnique (architectures, Reflect.field (Architecture, name.toUpperCase ())); + + } + + } + + if (element.has.exclude) { + + var exclude = substitute (element.att.exclude); + + if (Reflect.hasField (Architecture, exclude.toUpperCase ())) { + + architectures.remove (Reflect.field (Architecture, exclude.toUpperCase ())); + + } + + } + + case "launchImage", "splashscreen", "splashScreen": + + var path = ""; + + if (element.has.path) { + + path = PathHelper.combine (extensionPath, substitute (element.att.path)); + + } else { + + path = PathHelper.combine (extensionPath, substitute (element.att.name)); + + } + + var splashScreen = new SplashScreen (path); + + if (element.has.width) { + + splashScreen.width = Std.parseInt (substitute (element.att.width)); + + } + + if (element.has.height) { + + splashScreen.height = Std.parseInt (substitute (element.att.height)); + + } + + splashScreens.push (splashScreen); + + case "icon": + + var path = ""; + + if (element.has.path) { + + path = PathHelper.combine (extensionPath, substitute (element.att.path)); + + } else { + + path = PathHelper.combine (extensionPath, substitute (element.att.name)); + + } + + var icon = new Icon (path); + + if (element.has.size) { + + icon.size = icon.width = icon.height = Std.parseInt (substitute (element.att.size)); + + } + + if (element.has.width) { + + icon.width = Std.parseInt (substitute (element.att.width)); + + } + + if (element.has.height) { + + icon.height = Std.parseInt (substitute (element.att.height)); + + } + + icons.push (icon); + + case "source", "classpath": + + var path = ""; + + if (element.has.path) { + + path = PathHelper.combine (extensionPath, substitute (element.att.path)); + + } else { + + path = PathHelper.combine (extensionPath, substitute (element.att.name)); + + } + + sources.push (path); + + case "extension": + + // deprecated + + case "haxedef": + + if (element.has.remove) { + + haxedefs.remove (substitute (element.att.remove)); + + } else { + + var name = substitute (element.att.name); + var value = ""; + + if (element.has.value) { + + value = substitute (element.att.value); + + } + + haxedefs.set (name, value); + + } + + case "haxeflag", "compilerflag": + + var flag = substitute (element.att.name); + + if (element.has.value) { + + flag += " " + substitute (element.att.value); + + } + + haxeflags.push (substitute (flag)); + + case "window": + + parseWindowElement (element); + + case "assets": + + parseAssetsElement (element, extensionPath); + + case "library", "swf": + + if (element.has.handler) { + + if (element.has.type) { + + libraryHandlers.set (substitute (element.att.type), substitute (element.att.handler)); + + } + + } else { + + var path = null; + var name = ""; + var type = null; + var embed:Null = null; + var preload = false; + var generate = false; + var prefix = ""; + + if (element.has.path) { + + path = PathHelper.combine (extensionPath, substitute (element.att.path)); + + } + + if (element.has.name) { + + name = substitute (element.att.name); + + } + + if (element.has.id) { + + name = substitute (element.att.id); + + } + + if (element.has.type) { + + type = substitute (element.att.type); + + } + + if (element.has.embed) { + + embed = parseBool (element.att.embed); + + } + + if (element.has.preload) { + + preload = parseBool (element.att.preload); + + } + + if (element.has.generate) { + + generate = parseBool (element.att.generate); + + } + + if (element.has.prefix) { + + prefix = substitute (element.att.prefix); + + } + + libraries.push (new Library (path, name, type, embed, preload, generate, prefix)); + + } + + case "module": + + parseModuleElement (element, extensionPath); + + case "ssl": + + //if (wantSslCertificate()) + //parseSsl (element); + + case "sample": + + samplePaths.push (PathHelper.combine (extensionPath, substitute (element.att.path))); + + case "target": + + if (element.has.handler) { + + if (element.has.name) { + + targetHandlers.set (substitute (element.att.name), substitute (element.att.handler)); + + } + + } else if (element.has.path) { + + if (element.has.name) { + + targetHandlers.set (substitute (element.att.name), PathHelper.combine (extensionPath, substitute (element.att.path))); + + } + + } + + case "template": + + if (element.has.path) { + + if (element.has.haxelib) { + + var haxelibPath = HaxelibHelper.getPath (new Haxelib (substitute (element.att.haxelib)), true); + var path = PathHelper.combine (haxelibPath, substitute (element.att.path)); + templatePaths.push (path); + + } else { + + var path = PathHelper.combine (extensionPath, substitute (element.att.path)); + + if (FileSystem.exists (path) && !FileSystem.isDirectory (path)) { + + parseAssetsElement (element, extensionPath, true); + + } else { + + templatePaths.push (path); + + } + + } + + } else { + + parseAssetsElement (element, extensionPath, true); + + } + + case "templatePath": + + templatePaths.push (PathHelper.combine (extensionPath, substitute (element.att.name))); + + case "preloader": + + // deprecated + + app.preloader = substitute (element.att.name); + + case "output": + + // deprecated + + parseOutputElement (element, extensionPath); + + case "section": + + parseXML (element, "", extensionPath); + + case "certificate": + + var path = null; + + if (element.has.path) { + + path = element.att.path; + + } else if (element.has.keystore) { + + path = element.att.keystore; + + } + + if (path != null) { + + keystore = new Keystore (PathHelper.combine (extensionPath, substitute (element.att.path))); + + if (element.has.type) { + + keystore.type = substitute (element.att.type); + + } + + if (element.has.password) { + + keystore.password = substitute (element.att.password); + + } + + if (element.has.alias) { + + keystore.alias = substitute (element.att.alias); + + } + + if (element.has.resolve ("alias-password")) { + + keystore.aliasPassword = substitute (element.att.resolve ("alias-password")); + + } else if (element.has.alias_password) { + + keystore.aliasPassword = substitute (element.att.alias_password); + + } + + } + + if (element.has.identity) { + + config.set ("ios.identity", element.att.identity); + config.set ("tvos.identity", element.att.identity); + + } + + if (element.has.resolve ("team-id")) { + + config.set ("ios.team-id", element.att.resolve ("team-id")); + config.set ("tvos.team-id", element.att.resolve ("team-id")); + + } + + case "dependency": + + var name = ""; + var path = ""; + + if (element.has.path) { + + path = PathHelper.combine (extensionPath, substitute (element.att.path)); + + } + + if (element.has.name) { + + var foundName = substitute (element.att.name); + + if (StringTools.endsWith (foundName, ".a") || StringTools.endsWith (foundName, ".dll")) { + + path = PathHelper.combine (extensionPath, foundName); + + } else { + + name = foundName; + + } + + } + + var dependency = new Dependency (name, path); + + if (element.has.resolve ("force-load")) { + + dependency.forceLoad = (substitute (element.att.resolve ("force-load")) == "true"); + + } + + var i = dependencies.length; + + while (i-- > 0) { + + if ((name != "" && dependencies[i].name == name) || (path != "" && dependencies[i].path == path)) { + + dependencies.splice (i, 1); + + } + + } + + dependencies.push (dependency); + + case "android": + + // deprecated + + for (attribute in element.x.attributes ()) { + + var name = attribute; + var value = substitute (element.att.resolve (attribute)); + + switch (name) { + + case "minimum-sdk-version": + + config.set ("android.minimum-sdk-version", Std.parseInt (value)); + + case "target-sdk-version": + + config.set ("android.target-sdk-version", Std.parseInt (value)); + + case "install-location": + + config.set ("android.install-location", value); + + case "extension": + + var extensions = config.getArrayString ("android.extension"); + + if (extensions == null || extensions.indexOf (value) == -1) { + + config.push ("android.extension", value); + + } + + case "permission": + + var permissions = config.getArrayString ("android.permission"); + + if (permissions == null || permissions.indexOf (value) == -1) { + + config.push ("android.permission", value); + + } + + case "gradle-version": + + config.set ("android.gradle-version", value); + + default: + + name = formatAttributeName (attribute); + + } + + } + + case "cpp": + + // deprecated + + for (attribute in element.x.attributes ()) { + + var name = attribute; + var value = substitute (element.att.resolve (attribute)); + + switch (name) { + + case "build-library": + + config.set ("cpp.buildLibrary", value); + + default: + + name = formatAttributeName (attribute); + + } + + } + + case "ios": + + // deprecated + + if (target == Platform.IOS) { + + if (element.has.deployment) { + + var deployment = Std.parseFloat (substitute (element.att.deployment)); + + // If it is specified, assume the dev knows what he is doing! + config.set ("ios.deployment", deployment); + } + + if (element.has.binaries) { + + var binaries = substitute (element.att.binaries); + + switch (binaries) { + + case "fat": + + ArrayHelper.addUnique (architectures, Architecture.ARMV6); + ArrayHelper.addUnique (architectures, Architecture.ARMV7); + + case "armv6": + + ArrayHelper.addUnique (architectures, Architecture.ARMV6); + architectures.remove (Architecture.ARMV7); + + case "armv7": + + ArrayHelper.addUnique (architectures, Architecture.ARMV7); + architectures.remove (Architecture.ARMV6); + + } + + } + + if (element.has.devices) { + + config.set ("ios.device", substitute (element.att.devices).toLowerCase ()); + + } + + if (element.has.compiler) { + + config.set ("ios.compiler", substitute (element.att.compiler)); + + } + + if (element.has.resolve ("prerendered-icon")) { + + config.set ("ios.prerenderedIcon", substitute (element.att.resolve ("prerendered-icon"))); + + } + + if (element.has.resolve ("linker-flags")) { + + config.push ("ios.linker-flags", substitute (element.att.resolve ("linker-flags"))); + + } + + } + + case "tvos": + + // deprecated + + if (target == Platform.TVOS) { + + if (element.has.deployment) { + + var deployment = Std.parseFloat (substitute (element.att.deployment)); + + // If it is specified, assume the dev knows what he is doing! + config.set ("tvos.deployment", deployment); + } + + if (element.has.binaries) { + + var binaries = substitute (element.att.binaries); + + switch (binaries) { + + case "arm64": + + ArrayHelper.addUnique (architectures, Architecture.ARM64); + + } + + } + + if (element.has.devices) { + + config.set ("tvos.device", substitute (element.att.devices).toLowerCase ()); + + } + + if (element.has.compiler) { + + config.set ("tvos.compiler", substitute (element.att.compiler)); + + } + + if (element.has.resolve ("prerendered-icon")) { + + config.set ("tvos.prerenderedIcon", substitute (element.att.resolve ("prerendered-icon"))); + + } + + if (element.has.resolve ("linker-flags")) { + + config.push ("tvos.linker-flags", substitute (element.att.resolve ("linker-flags"))); + + } + + } + + case "config": + + config.parse (element, substitute); + + case "prebuild": + + parseCommandElement (element, preBuildCallbacks); + + case "postbuild": + + parseCommandElement (element, postBuildCallbacks); + + default : + + if (StringTools.startsWith (element.name, "config:")) { + + config.parse (element, substitute); + + } + + } + + } + + } + + } + + + private function parseWindowElement (element:Fast):Void { + + var id = 0; + + if (element.has.id) { + + id = Std.parseInt (substitute (element.att.id)); + + } + + while (id >= windows.length) { + + windows.push (ObjectHelper.copyFields (defaultWindow, {})); + + } + + for (attribute in element.x.attributes ()) { + + var name = attribute; + var value = substitute (element.att.resolve (attribute)); + + switch (name) { + + case "background": + + value = StringTools.replace (value, "#", ""); + + if (value.indexOf ("0x") == -1) { + + value = "0x" + value; + + } + + if (value == "0x" || (value.length == 10 && StringTools.startsWith (value, "0x00"))) { + + windows[id].background = null; + + } else { + + windows[id].background = Std.parseInt (value); + + } + + case "orientation": + + var orientation = Reflect.field (Orientation, Std.string (value).toUpperCase ()); + + if (orientation != null) { + + windows[id].orientation = orientation; + + } + + case "height", "width", "fps", "antialiasing": + + if (Reflect.hasField (windows[id], name)) { + + Reflect.setField (windows[id], name, Std.parseInt (value)); + + } + + case "parameters": + + if (Reflect.hasField (windows[id], name)) { + + Reflect.setField (windows[id], name, Std.string (value)); + + } + + case "allow-high-dpi": + + if (Reflect.hasField (windows[id], "allowHighDPI")) { + + Reflect.setField (windows[id], "allowHighDPI", value == "true"); + + } + + case "color-depth": + + if (Reflect.hasField (windows[id], "colorDepth")) { + + Reflect.setField (windows[id], "colorDepth", Std.parseInt (value)); + + } + + default: + + if (Reflect.hasField (windows[id], name)) { + + Reflect.setField (windows[id], name, value == "true"); + + } else if (Reflect.hasField (windows[id], formatAttributeName (name))) { + + Reflect.setField (windows[id], formatAttributeName (name), value == "true"); + + } + + } + + } + + } + + + public function process (projectFile:String, useExtensionPath:Bool):Void { + + var xml = null; + var extensionPath = ""; + + try { + + xml = new Fast (Xml.parse (File.getContent (projectFile)).firstElement ()); + extensionPath = Path.directory (projectFile); + + } catch (e:Dynamic) { + + Log.error ("\"" + projectFile + "\" contains invalid XML data", e); + + } + + parseXML (xml, "", extensionPath); + + } + + + private function substitute (string:String):String { + + var newString = string; + + while (doubleVarMatch.match (newString)) { + + newString = doubleVarMatch.matchedLeft () + "${" + ProjectHelper.replaceVariable (this, doubleVarMatch.matched (1)) + "}" + doubleVarMatch.matchedRight (); + + } + + while (varMatch.match (newString)) { + + newString = varMatch.matchedLeft () + ProjectHelper.replaceVariable (this, varMatch.matched (1)) + varMatch.matchedRight (); + + } + + return newString; + + } + + + +} diff --git a/src/lime/tools/SplashScreen.hx b/src/lime/tools/SplashScreen.hx new file mode 100644 index 000000000..5cd9f53bb --- /dev/null +++ b/src/lime/tools/SplashScreen.hx @@ -0,0 +1,32 @@ +package lime.tools; + + +class SplashScreen { + + + public var height:Int; + public var path:String; + public var width:Int; + + + public function new (path:String, width:Int = 0, height:Int = 0) { + + this.path = path; + this.width = width; + this.height = height; + + } + + + public function clone ():SplashScreen { + + var splashScreen = new SplashScreen (path); + splashScreen.width = width; + splashScreen.height = height; + + return splashScreen; + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/TVOSHelper.hx b/src/lime/tools/TVOSHelper.hx new file mode 100644 index 000000000..6b79d138e --- /dev/null +++ b/src/lime/tools/TVOSHelper.hx @@ -0,0 +1,454 @@ +package lime.tools; + + +import haxe.io.Path; +import hxp.PathHelper; +import hxp.ProcessHelper; +import hxp.Haxelib; +import hxp.*; +import lime.tools.Project; +import sys.io.Process; +import sys.FileSystem; + + +class TVOSHelper { + + + private static var initialized = false; + + + public static function build (project:Project, workingDirectory:String, additionalArguments:Array = null):Void { + + initialize (project); + + var commands = getXCodeArgs(project); + + if (project.targetFlags.exists ("archive")) { + + var configuration = project.environment.get ("CONFIGURATION"); + var platformName = project.environment.get ("PLATFORM_NAME"); + + commands.push ("archive"); + commands.push ("-scheme"); + commands.push (project.app.file); + commands.push ("-archivePath"); + commands.push (PathHelper.combine ("build", PathHelper.combine (configuration + "-" + platformName, project.app.file))); + + } + + if (additionalArguments != null) { + + commands = commands.concat (additionalArguments); + + } + + ProcessHelper.runCommand (workingDirectory, "xcodebuild", commands); + + } + + + public static function deploy (project:Project, workingDirectory:String):Void { + + initialize (project); + + var commands = getXCodeArgs (project); + var archiveCommands = commands.concat ([]); + + // generate xcarchive + var configuration = project.environment.get ("CONFIGURATION"); + var platformName = project.environment.get ("PLATFORM_NAME"); + + archiveCommands.push ("archive"); + archiveCommands.push ("-scheme"); + archiveCommands.push (project.app.file); + archiveCommands.push ("-archivePath"); + archiveCommands.push (PathHelper.combine ("build", PathHelper.combine (configuration + "-" + platformName, project.app.file))); + + ProcessHelper.runCommand (workingDirectory, "xcodebuild", archiveCommands); + + // generate IPA from xcarchive + var exportCommands = commands.concat ([]); + + var exportMethod = project.targetFlags.exists ("adhoc") ? "adhoc" + : project.targetFlags.exists ("development") ? "development" + : project.targetFlags.exists ("enterprise") ? "enterprise" + : "appstore"; + + exportCommands.push ("-exportArchive"); + exportCommands.push ("-archivePath"); + exportCommands.push (PathHelper.combine("build", PathHelper.combine (configuration + "-" + platformName, project.app.file + ".xcarchive"))); + exportCommands.push ("-exportOptionsPlist"); + exportCommands.push (PathHelper.combine (project.app.file, "exportOptions-" + exportMethod + ".plist")); + exportCommands.push ("-exportPath"); + exportCommands.push (PathHelper.combine ("dist", exportMethod)); + + ProcessHelper.runCommand (workingDirectory, "xcodebuild", exportCommands); + + } + + + private static function getXCodeArgs (project:Project):Array { + + var platformName = "appletvos"; + + if (project.targetFlags.exists ("simulator")) { + + platformName = "appletvsimulator"; + + } + + var configuration = "Release"; + + if (project.debug) { + + configuration = "Debug"; + + } + + var iphoneVersion = project.environment.get ("TVOS_VER"); + var commands = [ "-configuration", configuration, "PLATFORM_NAME=" + platformName, "SDKROOT=" + platformName + iphoneVersion ]; + + if (project.targetFlags.exists("simulator")) { + + commands.push ("-arch"); + commands.push ("x86_64"); + + } + + project.setenv ("PLATFORM_NAME", platformName); + project.setenv ("CONFIGURATION", configuration); + + // setting CONFIGURATION and PLATFORM_NAME in project.environment doesn't set them for xcodebuild so also pass via command line + var commands = [ "-configuration", configuration, "PLATFORM_NAME=" + platformName, "SDKROOT=" + platformName + iphoneVersion ]; + + if (project.targetFlags.exists ("simulator")) { + + commands.push ("-arch"); + commands.push ("x86_64"); + + } + + commands.push ("-project"); + commands.push (project.app.file + ".xcodeproj"); + + var xcodeVersions = getXcodeVersion() + .split(".") + .map(function (i:String) { + var ver = Std.parseInt(i); + return ver != null ? ver : 0; + }); + + if (xcodeVersions[0] >= 9) { + if (project.config.getBool('ios.allow-provisioning-updates', true)) { + commands.push("-allowProvisioningUpdates"); + } + if (project.config.getBool('ios.allow-provisioning-device-registration', true)) { + commands.push("-allowProvisioningDeviceRegistration"); + } + } + + return commands; + + } + + + private static function getIOSVersion (project:Project):Void { + + if (!project.environment.exists("TVOS_VER")) { + + if (!project.environment.exists("DEVELOPER_DIR")) { + + var proc = new Process ("xcode-select", ["--print-path"]); + var developer_dir = proc.stdout.readLine (); + proc.close (); + project.environment.set ("DEVELOPER_DIR", developer_dir); + + } + + var dev_path = project.environment.get ("DEVELOPER_DIR") + "/Platforms/AppleTVOS.platform/Developer/SDKs"; + + if (FileSystem.exists (dev_path)) { + + var best = ""; + var files = FileSystem.readDirectory (dev_path); + var extract_version = ~/^AppleTVOS(.*).sdk$/; + + for (file in files) { + + if (extract_version.match (file)) { + + var ver = extract_version.matched (1); + + if (ver > best) { + + best = ver; + + } + + } + + } + + if (best != "") { + + project.environment.set ("TVOS_VER", best); + + } + + } + + } + + } + + + private static function getOSXVersion ():String { + + var output = ProcessHelper.runProcess ("", "sw_vers", [ "-productVersion" ]); + return StringTools.trim (output); + + } + + + public static function getProvisioningFile ():String { + + var path = PathHelper.expand ("~/Library/MobileDevice/Provisioning Profiles"); + var files = FileSystem.readDirectory (path); + + for (file in files) { + + if (Path.extension (file) == "mobileprovision") { + + return path + "/" + file; + + } + + } + + return ""; + + } + + + public static function getSDKDirectory (project:Project):String { + + initialize (project); + + var platformName = "AppleTVOS"; + + if (project.targetFlags.exists ("simulator")) { + + platformName = "AppleTVSimulator"; + + } + + var process = new Process ("xcode-select", [ "--print-path" ]); + var directory = process.stdout.readLine (); + process.close (); + + if (directory == "" || directory.indexOf ("Run xcode-select") > -1) { + + directory = "/Applications/Xcode.app/Contents/Developer"; + + } + + directory += "/Platforms/" + platformName + ".platform/Developer/SDKs/" + platformName + project.environment.get ("TVOS_VER") + ".sdk"; + Log.info(directory); + return directory; + + } + + + private static function getXcodeVersion ():String { + + var output = ProcessHelper.runProcess ("", "xcodebuild", [ "-version" ]); + var firstLine = output.split ("\n").shift (); + + return StringTools.trim (firstLine.substring ("Xcode".length, firstLine.length)); + + } + + + private static function initialize (project:Project):Void { + + if (!initialized) { + + getIOSVersion (project); + + initialized = true; + + } + + } + + + public static function launch (project:Project, workingDirectory:String):Void { + + initialize (project); + + var configuration = "Release"; + + if (project.debug) { + + configuration = "Debug"; + + } + + if (project.targetFlags.exists ("simulator")) { + + var applicationPath = ""; + + if (Path.extension (workingDirectory) == "app" || Path.extension (workingDirectory) == "ipa") { + + applicationPath = workingDirectory; + + } else { + + applicationPath = workingDirectory + "/build/" + configuration + "-appletvsimulator/" + project.app.file + ".app"; + + } + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), #if lime "templates" #else "" #end) ].concat (project.templatePaths); + var launcher = PathHelper.findTemplate (templatePaths, "bin/ios-sim"); + Sys.command ("chmod", [ "+x", launcher ]); + + // device config + var defaultDevice = "apple-tv-1080p"; + var devices:Array = ["apple-tv-1080p"]; + var oldDevices:Map = ["appletv" => "apple-tv-1080p"]; + + var deviceFlag:String = null; + var deviceTypeID = null; + + // check if old device flag and convert to current + for (key in oldDevices.keys ()) { + + if (project.targetFlags.exists (key)) { + + deviceFlag = oldDevices[key]; + break; + + } + + } + + // check known device in command line args + if (deviceFlag == null) { + + for (i in 0...devices.length) { + + if (project.targetFlags.exists (devices[i])) { + + deviceFlag = devices[i]; + break; + + } + + } + + } + + // default to iphone 6 + if (deviceFlag == null) { + + deviceFlag = defaultDevice; + + } + + // check if device is available + // $ ios-sim showdevicetypes + var devicesOutput:String = ProcessHelper.runProcess ("", launcher, [ "showdevicetypes" ]); + var deviceTypeList:Array = devicesOutput.split ("\n"); + + for (i in 0...deviceTypeList.length) { + + var r = new EReg (deviceFlag + ",", "i"); + + if (r.match (deviceTypeList[i])) { + + deviceTypeID = deviceTypeList[i]; + break; + + } + + } + + if (deviceTypeID == null) { + + Log.warn("Device \"" + deviceFlag + "\" was not found"); + + } else { + + Log.info("Launch app on \"" + deviceTypeID + "\""); + + } + + // run command with --devicetypeid if exists + if (deviceTypeID != null) { + + ProcessHelper.runCommand ("", launcher, [ "launch", FileSystem.fullPath (applicationPath), /*"--sdk", project.environment.get ("IPHONE_VER"),*/ "--devicetypeid", deviceTypeID, "--timeout", "60" ]); + + } else { + + ProcessHelper.runCommand ("", launcher, [ "launch", FileSystem.fullPath (applicationPath), /*"--sdk", project.environment.get ("IPHONE_VER"), "--devicetypeid", deviceTypeID,*/ "--timeout", "60" ]); + + } + + } else { + + var applicationPath = ""; + + if (Path.extension (workingDirectory) == "app" || Path.extension (workingDirectory) == "ipa") { + + applicationPath = workingDirectory; + + } else { + + applicationPath = workingDirectory + "/build/" + configuration + "-appletvos/" + project.app.file + ".app"; + + } + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), #if lime "templates" #else "" #end) ].concat (project.templatePaths); + var launcher = PathHelper.findTemplate (templatePaths, "bin/ios-deploy"); + Sys.command ("chmod", [ "+x", launcher ]); + + var xcodeVersion = getXcodeVersion (); + + ProcessHelper.runCommand ("", launcher, [ "install", "--noninteractive", "--debug", "--timeout", "5", "--bundle", FileSystem.fullPath (applicationPath) ]); + + } + + } + + + public static function sign (project:Project, workingDirectory:String):Void { + + initialize (project); + + var configuration = "Release"; + + if (project.debug) { + + configuration = "Debug"; + + } + + var identity = project.config.getString ("tvos.identity", "tvOS Developer"); + + var commands = [ "-s", identity, "CODE_SIGN_IDENTITY=" + identity ]; + + if (project.config.exists ("tvos.provisioning-profile")) { + + commands.push ("PROVISIONING_PROFILE=" + project.config.getString ("tvos.provisioning-profile")); + + } + + var applicationPath = "build/" + configuration + "-appletvos/" + project.app.file + ".app"; + commands.push (applicationPath); + + ProcessHelper.runCommand (workingDirectory, "codesign", commands, true, true); + + } + + +} \ No newline at end of file diff --git a/src/lime/tools/TizenHelper.hx b/src/lime/tools/TizenHelper.hx new file mode 100644 index 000000000..639e90151 --- /dev/null +++ b/src/lime/tools/TizenHelper.hx @@ -0,0 +1,229 @@ +package lime.tools; + + +import haxe.crypto.Crc32; +import haxe.io.Bytes; +import haxe.io.Eof; +import hxp.PathHelper; +import hxp.PlatformHelper; +import hxp.ProcessHelper; +import hxp.Haxelib; +import lime.tools.Project; +import lime.tools.Platform; +import sys.FileSystem; + + +class TizenHelper { + + + private static var cacheID:String = null; + private static var cacheUUID:String = null; + + + public static function createPackage (project:Project, workingDirectory:String, targetPath:String):Void { + + var keystore = null; + var password = null; + + if (project.keystore != null) { + + keystore = PathHelper.tryFullPath (project.keystore.path); + password = project.keystore.password; + + if (password == null) { + + password = prompt ("Keystore password", true); + Sys.println (""); + + } + + } + + if (keystore == null) { + + var templatePaths = [ PathHelper.combine (PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)), #if lime "templates" #else "" #end) ].concat (project.templatePaths); + keystore = PathHelper.findTemplate (templatePaths, "bin/debug.p12"); + password = "1234"; + + } + + var packageName = getUUID (project) + "-" + project.meta.version + "-"; + + if (project.targetFlags.exists ("simulator")) { + + packageName += "i386"; + + } else { + + packageName += "arm"; + + } + + packageName += ".tpk"; + + if (FileSystem.exists (PathHelper.combine (workingDirectory, packageName))) { + + try { + + FileSystem.deleteFile ((PathHelper.combine (workingDirectory, packageName))); + + } catch (e:Dynamic) {} + + } + + runCommand (project, workingDirectory, "native-packaging" , [ "--sign-author-key", keystore, "--sign-author-pwd", password ]); + + } + + + public static function getUUID (project:Project):String { + + if (cacheID != project.meta.packageName) { + + if (project.meta.packageName != null || project.meta.packageName.length == 10 || project.meta.packageName.indexOf (".") == -1) { + + var bytes = Bytes.ofString (project.meta.packageName); + var crc = Crc32.make (bytes); + cacheUUID = StringHelper.generateUUID (10, null, crc); + + } else { + + cacheUUID = project.meta.packageName; + + } + + cacheID = project.meta.packageName; + + } + + return cacheUUID; + + } + + + public static function install (project:Project, workingDirectory:String):Void { + + var packageName = getUUID (project) + "-" + project.meta.version + "-"; + + if (project.targetFlags.exists ("simulator")) { + + packageName += "i386"; + + } else { + + packageName += "arm"; + + } + + packageName += ".tpk"; + + runCommand (project, "", "native-install", [ "--package", FileSystem.fullPath (workingDirectory + "/" + packageName) ]); + + } + + + public static function launch (project:Project):Void { + + runCommand (project, "", "native-run", [ "--package", getUUID (project) ]); + + } + + + private static function prompt (name:String, ?passwd:Bool):String { + + Sys.print (name + ": "); + + if (passwd) { + var s = new StringBuf (); + var c; + while ((c = Sys.getChar(false)) != 13) + s.addChar (c); + return s.toString (); + } + + try { + + return Sys.stdin ().readLine (); + + } catch (e:Eof) { + + return ""; + + } + + } + + + private static function runCommand (project:Project, workingDirectory:String, command:String, args:Array):Void { + + var sdkDirectory = ""; + + if (project.environment.exists ("TIZEN_SDK")) { + + sdkDirectory = project.environment.get ("TIZEN_SDK"); + + } else { + + if (PlatformHelper.hostPlatform == WINDOWS) { + + sdkDirectory = "C:\\Development\\Tizen\\tizen-sdk"; + + } else { + + sdkDirectory = "~/Development/Tizen/tizen-sdk"; + + } + + } + + ProcessHelper.runCommand (workingDirectory, PathHelper.combine (sdkDirectory, "tools/ide/bin/" + command), args); + + } + + + public static function trace (project:Project, follow:Bool = true):Void { + + /*var args = []; + + if (follow) { + + args.push ("-f"); + + } + + args.push (project.meta.packageName); + + runPalmCommand (project, "", "log", args);*/ + + var sdkDirectory = ""; + + if (project.environment.exists ("TIZEN_SDK")) { + + sdkDirectory = project.environment.get ("TIZEN_SDK"); + + } else { + + if (PlatformHelper.hostPlatform == WINDOWS) { + + sdkDirectory = "C:\\Development\\Tizen\\tizen-sdk"; + + } else { + + sdkDirectory = "~/Development/Tizen/tizen-sdk"; + + } + + } + + //var args = [ "--package", project.meta.packageName ]; + //var args = [ "dlog", project.meta.packageName + ":V", "*:E" ]; + var args = [ "dlog", project.app.file + ":V", "*:F" ]; + + ProcessHelper.runCommand ("", PathHelper.combine (sdkDirectory, "tools/sdb"), [ "dlog", "-c" ]); + ProcessHelper.runCommand ("", PathHelper.combine (sdkDirectory, "tools/sdb"), args); + //runCommand (project, "", "native-debug", [ "-p", project.meta.packageName ]); + + } + + +} diff --git a/src/lime/tools/WindowData.hx b/src/lime/tools/WindowData.hx new file mode 100644 index 000000000..34aae2bde --- /dev/null +++ b/src/lime/tools/WindowData.hx @@ -0,0 +1,36 @@ +package lime.tools; + + +typedef WindowData = { + + @:optional var width:Int; + @:optional var height:Int; + @:optional var x:Float; + @:optional var y:Float; + @:optional var background:Null; + @:optional var parameters:String; + @:optional var fps:Int; + @:optional var hardware:Bool; + @:optional var display:Int; + @:optional var resizable:Bool; + @:optional var borderless:Bool; + @:optional var vsync:Bool; + @:optional var fullscreen:Bool; + @:optional var allowHighDPI:Bool; + @:optional var alwaysOnTop:Bool; + @:optional var antialiasing:Int; + @:optional var orientation:Orientation; + @:optional var allowShaders:Bool; + @:optional var requireShaders:Bool; + @:optional var depthBuffer:Bool; + @:optional var stencilBuffer:Bool; + @:optional var title:String; + #if (js && html5) + @:optional var element:js.html.Element; + #end + @:optional var colorDepth:Int; + @:optional var minimized:Bool; + @:optional var maximized:Bool; + @:optional var hidden:Bool; + +} \ No newline at end of file diff --git a/src/lime/tools/XCodeHelper.hx b/src/lime/tools/XCodeHelper.hx new file mode 100644 index 000000000..c72aaece1 --- /dev/null +++ b/src/lime/tools/XCodeHelper.hx @@ -0,0 +1,149 @@ +package lime.tools; + + +import hxp.*; +import lime.tools.Project; + + +class XCodeHelper { + + + private static inline var DEFAULT_IPAD_SIMULATOR = "ipad-air"; + private static inline var DEFAULT_IPHONE_SIMULATOR = "iphone-6"; + + + private static function extractSimulatorFlagName (line:String):String { + + var device = line.substring (0, line.indexOf ("(") - 1); + device = device.toLowerCase (); + device = StringTools.replace (device, " ", "-"); + return device; + + } + + + private static function extractSimulatorFullName (line:String):String { + + var name = ""; + + if (line.indexOf ("inch") > -1 || line.indexOf ("generation") > -1) { + + name = line.substring (0, line.indexOf (")") + 1); + + } else { + + name = line.substring (0, line.indexOf ("(") - 1); + + } + + return name; + + } + + + private static function extractSimulatorID (line:String):String { + + var id = line.substring (line.indexOf ("(") + 1, line.indexOf (")")); + + if (id.indexOf ("inch") > -1 || id.indexOf ("generation") > -1) { + + var startIndex = line.indexOf (")") + 2; + id = line.substring (line.indexOf ("(", startIndex) + 1, line.indexOf (")", startIndex)); + + } + + return id; + + } + + + public static function getSelectedSimulator (project:Project):SimulatorInfo { + + var output = getSimulators (); + var lines = output.split ("\n"); + var foundSection = false; + var device = ""; + var deviceID = ""; + var deviceName = ""; + var devices = new Map (); + var currentDevice:SimulatorInfo = null; + + for (line in lines) { + + if (StringTools.startsWith (line, "--")) { + + if (line.indexOf ("iOS") > -1) { + + foundSection = true; + + } else if (foundSection) { + + break; + + } + + } else if (foundSection) { + + deviceName = extractSimulatorFullName (StringTools.trim (line)); + deviceID = extractSimulatorID (StringTools.trim (line)); + device = extractSimulatorFlagName (StringTools.trim (line)); + devices.set (device, { id: deviceID, name: deviceName }); + + if (project.targetFlags.exists (device)) { + + currentDevice = devices.get (device); + break; + + } + + } + } + + if (currentDevice == null) { + + if (project.targetFlags.exists ("ipad")) { + + currentDevice = devices.get (DEFAULT_IPAD_SIMULATOR); + + } else { + + currentDevice = devices.get (DEFAULT_IPHONE_SIMULATOR); + + } + } + + return currentDevice; + + } + + + public static function getSimulatorID (project:Project):String { + + return getSelectedSimulator (project).id; + + } + + + public static function getSimulatorName (project:Project):String { + + return getSelectedSimulator (project).name; + + } + + + private static function getSimulators ():String { + + return ProcessHelper.runProcess ("", "xcrun", [ "simctl", "list", "devices" ]); + + } + + +} + + +private typedef SimulatorInfo = { + + public var id:String; + public var name:String; + +} \ No newline at end of file diff --git a/tools/CommandLineTools.hx b/tools/CommandLineTools.hx index b418d20d6..e203e9811 100644 --- a/tools/CommandLineTools.hx +++ b/tools/CommandLineTools.hx @@ -10,6 +10,8 @@ import haxe.io.Path; import haxe.rtti.Meta; import hxp.*; import lime.system.CFFI; +import lime.tools.Project; +import lime.tools.*; import sys.io.File; import sys.io.Process; import sys.FileSystem; @@ -18,7 +20,7 @@ import utils.CreateTemplate; import utils.JavaExternGenerator; import utils.PlatformSetup; -@:access(hxp.Project) +@:access(lime.tools.Project) class CommandLineTools { @@ -67,7 +69,7 @@ class CommandLineTools { if (targetFlags.exists ("openfl")) { - LogHelper.accentColor = "\x1b[36;1m"; + Log.accentColor = "\x1b[36;1m"; commandName = "openfl"; defaultLibrary = "openfl"; defaultLibraryName = "OpenFL"; @@ -80,7 +82,7 @@ class CommandLineTools { } - if (LogHelper.verbose && command != "help" && command != "") { + if (Log.verbose && command != "help" && command != "") { displayInfo (); Sys.println (""); @@ -136,7 +138,7 @@ class CommandLineTools { if (words.length < 1 || words.length > 2) { - LogHelper.error ("Incorrect number of arguments for command '" + command + "'"); + Log.error ("Incorrect number of arguments for command '" + command + "'"); return; } @@ -148,7 +150,7 @@ class CommandLineTools { if (words.length < 1 || words.length > 2) { - LogHelper.error ("Incorrect number of arguments for command '" + command + "'"); + Log.error ("Incorrect number of arguments for command '" + command + "'"); return; } @@ -262,38 +264,39 @@ class CommandLineTools { } for (targetName in targets) { - var target = null; + + var target:Platform = null; switch (targetName) { case "cpp": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("cpp", ""); case "neko": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("neko", ""); case "hl": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("hl", ""); case "java": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("java", ""); case "nodejs": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("nodejs", ""); case "cs": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("cs", ""); case "iphone", "iphoneos": @@ -448,9 +451,9 @@ class CommandLineTools { project = initializeProject (project, targetName); buildProject (project); - if (LogHelper.verbose) { + if (Log.verbose) { - LogHelper.println (""); + Log.println (""); } @@ -462,7 +465,7 @@ class CommandLineTools { if (words.length < 1 || words.length > 2) { - LogHelper.error ("Incorrect number of arguments for command '" + command + "'"); + Log.error ("Incorrect number of arguments for command '" + command + "'"); return; } @@ -475,7 +478,7 @@ class CommandLineTools { default: - LogHelper.error ("'" + command + "' is not a valid command"); + Log.error ("'" + command + "' is not a valid command"); } @@ -551,7 +554,7 @@ class CommandLineTools { case MAC: - //if (PlatformHelper.hostArchitecture == Architecture.X64) { + //if (PlatformHelper.hostArchitecture == X64) { untyped $loader.path = $array (path + "Mac64/", $loader.path); @@ -572,11 +575,11 @@ class CommandLineTools { } - if (raspberryPi || PlatformHelper.hostArchitecture == Architecture.ARMV6 || PlatformHelper.hostArchitecture == Architecture.ARMV7) { + if (raspberryPi || PlatformHelper.hostArchitecture == ARMV6 || PlatformHelper.hostArchitecture == ARMV7) { untyped $loader.path = $array (path + "RPi/", $loader.path); - } else if (PlatformHelper.hostArchitecture == Architecture.X64) { + } else if (PlatformHelper.hostArchitecture == X64) { untyped $loader.path = $array (path + "Linux64/", $loader.path); @@ -610,7 +613,7 @@ class CommandLineTools { } - LogHelper.info ("", LogHelper.accentColor + "Using target platform: " + Std.string (project.target).toUpperCase () + "\x1b[0m"); + Log.info ("", Log.accentColor + "Using target platform: " + Std.string (project.target).toUpperCase () + "\x1b[0m"); var handler = project.targetHandlers.get (Std.string (project.target)); var projectData = Serializer.run (project); @@ -623,8 +626,8 @@ class CommandLineTools { var args = [ command, temporaryFile ]; - if (LogHelper.verbose) args.push ("-verbose"); - if (!LogHelper.enableColor) args.push ("-nocolor"); + if (Log.verbose) args.push ("-verbose"); + if (!Log.enableColor) args.push ("-nocolor"); if (!traceEnabled) args.push ("-notrace"); if (additionalArguments.length > 0) { @@ -729,7 +732,7 @@ class CommandLineTools { } else { - LogHelper.error ("\"" + Std.string (project.target) + "\" is an unknown target"); + Log.error ("\"" + Std.string (project.target) + "\" is an unknown target"); } @@ -755,7 +758,7 @@ class CommandLineTools { private function createTemplate () { - LogHelper.info ("", LogHelper.accentColor + "Running command: CREATE\x1b[0m"); + Log.info ("", Log.accentColor + "Running command: CREATE\x1b[0m"); if (words.length > 0) { @@ -847,7 +850,7 @@ class CommandLineTools { if (words.length == 0) { - LogHelper.println (File.getContent (ConfigHelper.getConfigPath ())); + Log.println (File.getContent (ConfigHelper.getConfigPath ())); } else if (words.length == 1) { @@ -855,11 +858,11 @@ class CommandLineTools { if (value != null) { - LogHelper.println (value); + Log.println (value); } else { - LogHelper.error ("\"" + words[0] + "\" is undefined"); + Log.error ("\"" + words[0] + "\" is undefined"); } @@ -921,8 +924,8 @@ class CommandLineTools { if (commands.exists (command)) { - LogHelper.println ("\x1b[1m" + commands.get (command) + "\x1b[0m"); - LogHelper.println (""); + Log.println ("\x1b[1m" + commands.get (command) + "\x1b[0m"); + Log.println (""); } @@ -930,66 +933,66 @@ class CommandLineTools { case "setup": - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " setup\x1b[0m \x1b[3;37m(target)\x1b[0m \x1b[3;37m[options]\x1b[0m"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " setup\x1b[0m \x1b[3;37m(target)\x1b[0m \x1b[3;37m[options]\x1b[0m"); case "clean", "update", "build", "run", "test", "display", "deploy", "trace": - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " " + command + "\x1b[0m \x1b[3;37m(project)\x1b[0m \x1b[1m\x1b[0m \x1b[3;37m[options]\x1b[0m"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " " + command + "\x1b[0m \x1b[3;37m(project)\x1b[0m \x1b[1m\x1b[0m \x1b[3;37m[options]\x1b[0m"); isProjectCommand = true; isBuildCommand = true; case "create": - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " create\x1b[0m \x1b[3;37m(library)\x1b[0m \x1b[1mproject\x1b[0m \x1b[3;37m(directory)\x1b[0m \x1b[3;37m[options]\x1b[0m"); - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " create\x1b[0m \x1b[3;37m(library)\x1b[0m \x1b[1mextension\x1b[0m \x1b[3;37m(directory)\x1b[0m \x1b[3;37m[options]\x1b[0m"); - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " create\x1b[0m \x1b[3;37m(library)\x1b[0m \x1b[1m\x1b[0m \x1b[3;37m(directory)\x1b[0m \x1b[3;37m[options]\x1b[0m"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " create\x1b[0m \x1b[3;37m(library)\x1b[0m \x1b[1mproject\x1b[0m \x1b[3;37m(directory)\x1b[0m \x1b[3;37m[options]\x1b[0m"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " create\x1b[0m \x1b[3;37m(library)\x1b[0m \x1b[1mextension\x1b[0m \x1b[3;37m(directory)\x1b[0m \x1b[3;37m[options]\x1b[0m"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " create\x1b[0m \x1b[3;37m(library)\x1b[0m \x1b[1m\x1b[0m \x1b[3;37m(directory)\x1b[0m \x1b[3;37m[options]\x1b[0m"); case "rebuild": - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " rebuild\x1b[0m \x1b[3;37m(library)\x1b[0m \x1b[3;37m(target)\x1b[0m \x1b[3;37m[options]\x1b[0m"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " rebuild\x1b[0m \x1b[3;37m(library)\x1b[0m \x1b[3;37m(target)\x1b[0m \x1b[3;37m[options]\x1b[0m"); isBuildCommand = true; case "config": - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " config\x1b[0m \x1b[3;37m(name)\x1b[0m \x1b[3;37m(value)\x1b[0m \x1b[3;37m[options]\x1b[0m"); - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " config remove \x1b[0m \x1b[3;37m[options]\x1b[0m"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " config\x1b[0m \x1b[3;37m(name)\x1b[0m \x1b[3;37m(value)\x1b[0m \x1b[3;37m[options]\x1b[0m"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " config remove \x1b[0m \x1b[3;37m[options]\x1b[0m"); case "install", "remove", "upgrade": - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " " + command + "\x1b[0m \x1b[3;37m(library)\x1b[0m \x1b[3;37m[options]\x1b[0m"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " " + command + "\x1b[0m \x1b[3;37m(library)\x1b[0m \x1b[3;37m[options]\x1b[0m"); case "process": - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " process \x1b[0m \x1b[3;37m(directory)\x1b[0m \x1b[3;37m[options]\x1b[0m"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " process \x1b[0m \x1b[3;37m(directory)\x1b[0m \x1b[3;37m[options]\x1b[0m"); default: displayInfo (); - LogHelper.println (""); - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " \x1b[0m \x1b[3;37m[arguments]\x1b[0m"); - LogHelper.println (""); - LogHelper.println (" " + LogHelper.accentColor + "Basic Commands:" + LogHelper.resetColor); - LogHelper.println (""); + Log.println (""); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + commandName + " \x1b[0m \x1b[3;37m[arguments]\x1b[0m"); + Log.println (""); + Log.println (" " + Log.accentColor + "Basic Commands:" + Log.resetColor); + Log.println (""); for (command in basicCommands) { - LogHelper.println (" \x1b[1m" + command + "\x1b[0m -- " + commands.get (command)); + Log.println (" \x1b[1m" + command + "\x1b[0m -- " + commands.get (command)); } - LogHelper.println (""); - LogHelper.println (" " + LogHelper.accentColor + "Additional Commands:" + LogHelper.resetColor); - LogHelper.println (""); + Log.println (""); + Log.println (" " + Log.accentColor + "Additional Commands:" + Log.resetColor); + Log.println (""); for (command in additionalCommands) { - LogHelper.println (" \x1b[1m" + command + "\x1b[0m -- " + commands.get (command)); + Log.println (" \x1b[1m" + command + "\x1b[0m -- " + commands.get (command)); } - LogHelper.println (""); - LogHelper.println ("For additional help, run \x1b[1m" + commandName + " help \x1b[0m"); + Log.println (""); + Log.println ("For additional help, run \x1b[1m" + commandName + " help \x1b[0m"); return; @@ -997,109 +1000,109 @@ class CommandLineTools { if (isBuildCommand || command == "setup") { - LogHelper.println (""); - LogHelper.println (" " + LogHelper.accentColor + "Targets:" + LogHelper.resetColor); - LogHelper.println (""); - LogHelper.println (" \x1b[1mair\x1b[0m -- Create an AIR application"); - LogHelper.println (" \x1b[1mandroid\x1b[0m -- Create an Android application"); - //LogHelper.println (" \x1b[1mblackberry\x1b[0m -- Create a BlackBerry application"); - LogHelper.println (" \x1b[1memscripten\x1b[0m -- Create an Emscripten application"); - LogHelper.println (" \x1b[1mflash\x1b[0m -- Create a Flash SWF application"); - LogHelper.println (" \x1b[1mhtml5\x1b[0m -- Create an HTML5 application"); - LogHelper.println (" \x1b[1mios\x1b[0m -- Create an iOS application"); - LogHelper.println (" \x1b[1mlinux\x1b[0m -- Create a Linux application"); - LogHelper.println (" \x1b[1mmac\x1b[0m -- Create a macOS application"); - //LogHelper.println (" \x1b[1mtizen\x1b[0m -- Create a Tizen application"); - LogHelper.println (" \x1b[1mtvos\x1b[0m -- Create a tvOS application"); - //LogHelper.println (" \x1b[1mwebos\x1b[0m -- Create a webOS application"); - LogHelper.println (" \x1b[1mwindows\x1b[0m -- Create a Windows application"); + Log.println (""); + Log.println (" " + Log.accentColor + "Targets:" + Log.resetColor); + Log.println (""); + Log.println (" \x1b[1mair\x1b[0m -- Create an AIR application"); + Log.println (" \x1b[1mandroid\x1b[0m -- Create an Android application"); + //Log.println (" \x1b[1mblackberry\x1b[0m -- Create a BlackBerry application"); + Log.println (" \x1b[1memscripten\x1b[0m -- Create an Emscripten application"); + Log.println (" \x1b[1mflash\x1b[0m -- Create a Flash SWF application"); + Log.println (" \x1b[1mhtml5\x1b[0m -- Create an HTML5 application"); + Log.println (" \x1b[1mios\x1b[0m -- Create an iOS application"); + Log.println (" \x1b[1mlinux\x1b[0m -- Create a Linux application"); + Log.println (" \x1b[1mmac\x1b[0m -- Create a macOS application"); + //Log.println (" \x1b[1mtizen\x1b[0m -- Create a Tizen application"); + Log.println (" \x1b[1mtvos\x1b[0m -- Create a tvOS application"); + //Log.println (" \x1b[1mwebos\x1b[0m -- Create a webOS application"); + Log.println (" \x1b[1mwindows\x1b[0m -- Create a Windows application"); - LogHelper.println (""); - LogHelper.println (" " + LogHelper.accentColor + "Target Aliases:" + LogHelper.resetColor); - LogHelper.println (""); - LogHelper.println (" \x1b[1mcpp\x1b[0m -- Alias for host platform (using \x1b[1m-cpp\x1b[0m)"); - LogHelper.println (" \x1b[1mneko\x1b[0m -- Alias for host platform (using \x1b[1m-neko\x1b[0m)"); - LogHelper.println (" \x1b[1mmacos\x1b[0m -- Alias for \x1b[1mmac\x1b[0m"); - LogHelper.println (" \x1b[1mnodejs\x1b[0m -- Alias for host platform (using \x1b[1m-nodejs\x1b[0m)"); - LogHelper.println (" \x1b[1mjava\x1b[0m -- Alias for host platform (using \x1b[1m-java\x1b[0m)"); - LogHelper.println (" \x1b[1mcs\x1b[0m -- Alias for host platform (using \x1b[1m-cs\x1b[0m)"); - LogHelper.println (" \x1b[1mhl\x1b[0m -- Alias for host platform (using \x1b[1m-hl\x1b[0m)"); - LogHelper.println (" \x1b[1muwp\x1b[0;3m/\x1b[0m\x1b[1mwinjs\x1b[0m -- Alias for \x1b[1mwindows -uwp\x1b[0m"); - // LogHelper.println (" \x1b[1miphone\x1b[0;3m/\x1b[0m\x1b[1miphoneos\x1b[0m -- \x1b[1mios\x1b[0m"); - // LogHelper.println (" \x1b[1miphonesim\x1b[0m -- Alias for \x1b[1mios -simulator\x1b[0m"); - // LogHelper.println (" \x1b[1mappletv\x1b[0;3m/\x1b[0m\x1b[1mappletvos\x1b[0m -- Alias for \x1b[1mtvos\x1b[0m"); - // LogHelper.println (" \x1b[1mappletvsim\x1b[0m -- Alias for \x1b[1mtvos -simulator\x1b[0m"); - LogHelper.println (" \x1b[1mrpi\x1b[0;3m/\x1b[0m\x1b[1mraspberrypi\x1b[0m -- Alias for \x1b[1mlinux -rpi\x1b[0m"); - LogHelper.println (" \x1b[1melectron\x1b[0m -- Alias for \x1b[1mhtml5 -electron\x1b[0m"); - LogHelper.println (" \x1b[1mwebassembly\x1b[0;3m/\x1b[0m\x1b[1mwasm\x1b[0m -- Alias for \x1b[1memscripten -webassembly\x1b[0m"); + Log.println (""); + Log.println (" " + Log.accentColor + "Target Aliases:" + Log.resetColor); + Log.println (""); + Log.println (" \x1b[1mcpp\x1b[0m -- Alias for host platform (using \x1b[1m-cpp\x1b[0m)"); + Log.println (" \x1b[1mneko\x1b[0m -- Alias for host platform (using \x1b[1m-neko\x1b[0m)"); + Log.println (" \x1b[1mmacos\x1b[0m -- Alias for \x1b[1mmac\x1b[0m"); + Log.println (" \x1b[1mnodejs\x1b[0m -- Alias for host platform (using \x1b[1m-nodejs\x1b[0m)"); + Log.println (" \x1b[1mjava\x1b[0m -- Alias for host platform (using \x1b[1m-java\x1b[0m)"); + Log.println (" \x1b[1mcs\x1b[0m -- Alias for host platform (using \x1b[1m-cs\x1b[0m)"); + Log.println (" \x1b[1mhl\x1b[0m -- Alias for host platform (using \x1b[1m-hl\x1b[0m)"); + Log.println (" \x1b[1muwp\x1b[0;3m/\x1b[0m\x1b[1mwinjs\x1b[0m -- Alias for \x1b[1mwindows -uwp\x1b[0m"); + // Log.println (" \x1b[1miphone\x1b[0;3m/\x1b[0m\x1b[1miphoneos\x1b[0m -- \x1b[1mios\x1b[0m"); + // Log.println (" \x1b[1miphonesim\x1b[0m -- Alias for \x1b[1mios -simulator\x1b[0m"); + // Log.println (" \x1b[1mappletv\x1b[0;3m/\x1b[0m\x1b[1mappletvos\x1b[0m -- Alias for \x1b[1mtvos\x1b[0m"); + // Log.println (" \x1b[1mappletvsim\x1b[0m -- Alias for \x1b[1mtvos -simulator\x1b[0m"); + Log.println (" \x1b[1mrpi\x1b[0;3m/\x1b[0m\x1b[1mraspberrypi\x1b[0m -- Alias for \x1b[1mlinux -rpi\x1b[0m"); + Log.println (" \x1b[1melectron\x1b[0m -- Alias for \x1b[1mhtml5 -electron\x1b[0m"); + Log.println (" \x1b[1mwebassembly\x1b[0;3m/\x1b[0m\x1b[1mwasm\x1b[0m -- Alias for \x1b[1memscripten -webassembly\x1b[0m"); } - LogHelper.println (""); - LogHelper.println (" " + LogHelper.accentColor + "Options:" + LogHelper.resetColor); - LogHelper.println (""); + Log.println (""); + Log.println (" " + Log.accentColor + "Options:" + Log.resetColor); + Log.println (""); if (isBuildCommand) { - LogHelper.println (" \x1b[1m-D\x1b[0;3mvalue\x1b[0m -- Specify a define to use when processing other commands"); - LogHelper.println (" \x1b[1m-debug\x1b[0m -- Use debug configuration instead of release"); - LogHelper.println (" \x1b[1m-final\x1b[0m -- Use final configuration instead of release"); + Log.println (" \x1b[1m-D\x1b[0;3mvalue\x1b[0m -- Specify a define to use when processing other commands"); + Log.println (" \x1b[1m-debug\x1b[0m -- Use debug configuration instead of release"); + Log.println (" \x1b[1m-final\x1b[0m -- Use final configuration instead of release"); } - LogHelper.println (" \x1b[1m-v\x1b[0;3m/\x1b[0m\x1b[1m-verbose\x1b[0m -- Print additional information (when available)"); + Log.println (" \x1b[1m-v\x1b[0;3m/\x1b[0m\x1b[1m-verbose\x1b[0m -- Print additional information (when available)"); if (isBuildCommand && command != "run" && command != "trace") { - LogHelper.println (" \x1b[1m-clean\x1b[0m -- Add a \"clean\" action before running the current command"); + Log.println (" \x1b[1m-clean\x1b[0m -- Add a \"clean\" action before running the current command"); } - LogHelper.println (" \x1b[1m-nocolor\x1b[0m -- Disable ANSI format codes in output"); + Log.println (" \x1b[1m-nocolor\x1b[0m -- Disable ANSI format codes in output"); if (command == "run" || command == "test") { - LogHelper.println (" \x1b[1m-notrace\x1b[0m -- Disable trace output during run or test command"); + Log.println (" \x1b[1m-notrace\x1b[0m -- Disable trace output during run or test command"); } - LogHelper.println (" \x1b[1m-dryrun\x1b[0m -- Execute the requested command without making changes"); + Log.println (" \x1b[1m-dryrun\x1b[0m -- Execute the requested command without making changes"); if (isProjectCommand && command != "run" && command != "trace") { - LogHelper.println (" \x1b[1m-xml\x1b[0m -- Generate XML type information, useful for documentation"); + Log.println (" \x1b[1m-xml\x1b[0m -- Generate XML type information, useful for documentation"); } if (command == "run" || command == "test") { - LogHelper.println (" \x1b[1m--\x1b[0;3m/\x1b[0m\x1b[1m-args\x1b[0m ... -- Pass additional arguments at launch"); + Log.println (" \x1b[1m--\x1b[0;3m/\x1b[0m\x1b[1m-args\x1b[0m ... -- Pass additional arguments at launch"); } if (isProjectCommand) { - LogHelper.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-cpp\x1b[0m -- Build with C++ (default behavior)"); - LogHelper.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-neko\x1b[0m -- Build with Neko instead of C++"); - LogHelper.println (" \x1b[3m(windows|mac|ios|android)\x1b[0m \x1b[1m-air\x1b[0m -- Build with AIR instead of C++"); + Log.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-cpp\x1b[0m -- Build with C++ (default behavior)"); + Log.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-neko\x1b[0m -- Build with Neko instead of C++"); + Log.println (" \x1b[3m(windows|mac|ios|android)\x1b[0m \x1b[1m-air\x1b[0m -- Build with AIR instead of C++"); } if (isBuildCommand) { - LogHelper.println (" \x1b[3m(windows|mac|linux|android)\x1b[0m \x1b[1m-static\x1b[0m -- Compile as a static C++ executable"); - LogHelper.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-32\x1b[0m -- Compile for 32-bit instead of the OS default"); - LogHelper.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-64\x1b[0m -- Compile for 64-bit instead of the OS default"); - LogHelper.println (" \x1b[3m(ios|android)\x1b[0m \x1b[1m-armv6\x1b[0m -- Compile for ARMv6 instead of the OS defaults"); - LogHelper.println (" \x1b[3m(ios|android)\x1b[0m \x1b[1m-armv7\x1b[0m -- Compile for ARMv7 instead of the OS defaults"); - LogHelper.println (" \x1b[3m(ios|android)\x1b[0m \x1b[1m-armv7s\x1b[0m -- Compile for ARMv7s instead of the OS defaults"); - LogHelper.println (" \x1b[3m(ios)\x1b[0m \x1b[1m-arm64\x1b[0m -- Compile for ARM64 instead of the OS defaults"); + Log.println (" \x1b[3m(windows|mac|linux|android)\x1b[0m \x1b[1m-static\x1b[0m -- Compile as a static C++ executable"); + Log.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-32\x1b[0m -- Compile for 32-bit instead of the OS default"); + Log.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-64\x1b[0m -- Compile for 64-bit instead of the OS default"); + Log.println (" \x1b[3m(ios|android)\x1b[0m \x1b[1m-armv6\x1b[0m -- Compile for ARMv6 instead of the OS defaults"); + Log.println (" \x1b[3m(ios|android)\x1b[0m \x1b[1m-armv7\x1b[0m -- Compile for ARMv7 instead of the OS defaults"); + Log.println (" \x1b[3m(ios|android)\x1b[0m \x1b[1m-armv7s\x1b[0m -- Compile for ARMv7s instead of the OS defaults"); + Log.println (" \x1b[3m(ios)\x1b[0m \x1b[1m-arm64\x1b[0m -- Compile for ARM64 instead of the OS defaults"); } if (isProjectCommand) { - LogHelper.println (" \x1b[3m(ios)\x1b[0m \x1b[1m-archive\x1b[0m -- Generate iOS archive during build"); + Log.println (" \x1b[3m(ios)\x1b[0m \x1b[1m-archive\x1b[0m -- Generate iOS archive during build"); } @@ -1107,63 +1110,63 @@ class CommandLineTools { if (command != "run" && command != "trace") { - LogHelper.println (" \x1b[3m(ios)\x1b[0m \x1b[1m-xcode\x1b[0m -- Launch the generated Xcode project"); + Log.println (" \x1b[3m(ios)\x1b[0m \x1b[1m-xcode\x1b[0m -- Launch the generated Xcode project"); } - //LogHelper.println (" \x1b[3m(ios|blackberry|tizen|tvos|webos)\x1b[0m \x1b[1m-simulator\x1b[0m -- Target the device simulator"); - LogHelper.println (" \x1b[3m(ios|tvos)\x1b[0m \x1b[1m-simulator\x1b[0m -- Target the device simulator"); - LogHelper.println (" \x1b[3m(ios)\x1b[0m \x1b[1m-simulator -ipad\x1b[0m -- Build/test for the iPad Simulator"); - LogHelper.println (" \x1b[3m(android)\x1b[0m \x1b[1m-emulator\x1b[0m -- Target the device emulator"); - LogHelper.println (" \x1b[3m(flash)\x1b[0m \x1b[1m-web\x1b[0m -- Test Flash target using a web template"); - LogHelper.println (" \x1b[3m(air)\x1b[0m \x1b[1m-ios\x1b[0m -- Target iOS instead of AIR desktop"); - LogHelper.println (" \x1b[3m(air)\x1b[0m \x1b[1m-android\x1b[0m -- Target Android instead of AIR desktop"); + //Log.println (" \x1b[3m(ios|blackberry|tizen|tvos|webos)\x1b[0m \x1b[1m-simulator\x1b[0m -- Target the device simulator"); + Log.println (" \x1b[3m(ios|tvos)\x1b[0m \x1b[1m-simulator\x1b[0m -- Target the device simulator"); + Log.println (" \x1b[3m(ios)\x1b[0m \x1b[1m-simulator -ipad\x1b[0m -- Build/test for the iPad Simulator"); + Log.println (" \x1b[3m(android)\x1b[0m \x1b[1m-emulator\x1b[0m -- Target the device emulator"); + Log.println (" \x1b[3m(flash)\x1b[0m \x1b[1m-web\x1b[0m -- Test Flash target using a web template"); + Log.println (" \x1b[3m(air)\x1b[0m \x1b[1m-ios\x1b[0m -- Target iOS instead of AIR desktop"); + Log.println (" \x1b[3m(air)\x1b[0m \x1b[1m-android\x1b[0m -- Target Android instead of AIR desktop"); if (command == "run" || command == "test") { - LogHelper.println (" \x1b[3m(emscripten|html5|flash)\x1b[0m \x1b[1m-nolaunch\x1b[0m -- Begin test server without launching"); - //LogHelper.println (" \x1b[3m(html5)\x1b[0m \x1b[1m-minify\x1b[0m -- Minify output using the Google Closure compiler"); - LogHelper.println (" \x1b[3m(emscripten|html5)\x1b[0m \x1b[1m-minify\x1b[0m -- Minify application file"); - //LogHelper.println (" \x1b[3m(html5)\x1b[0m \x1b[1m-minify -yui\x1b[0m -- Minify output using the YUI compressor"); - LogHelper.println (" \x1b[3m(emscripten|html5|flash)\x1b[0m \x1b[1m--port=\x1b[0;3mvalue\x1b[0m -- Set port for test server"); + Log.println (" \x1b[3m(emscripten|html5|flash)\x1b[0m \x1b[1m-nolaunch\x1b[0m -- Begin test server without launching"); + //Log.println (" \x1b[3m(html5)\x1b[0m \x1b[1m-minify\x1b[0m -- Minify output using the Google Closure compiler"); + Log.println (" \x1b[3m(emscripten|html5)\x1b[0m \x1b[1m-minify\x1b[0m -- Minify application file"); + //Log.println (" \x1b[3m(html5)\x1b[0m \x1b[1m-minify -yui\x1b[0m -- Minify output using the YUI compressor"); + Log.println (" \x1b[3m(emscripten|html5|flash)\x1b[0m \x1b[1m--port=\x1b[0;3mvalue\x1b[0m -- Set port for test server"); } if (command != "run" && command != "trace") { - LogHelper.println (" \x1b[3m(emscripten)\x1b[0m \x1b[1m-webassembly\x1b[0m -- Compile for WebAssembly instead of asm.js"); + Log.println (" \x1b[3m(emscripten)\x1b[0m \x1b[1m-webassembly\x1b[0m -- Compile for WebAssembly instead of asm.js"); } - LogHelper.println (""); - LogHelper.println (" " + LogHelper.accentColor + "Experimental Options:" + LogHelper.resetColor); - LogHelper.println (""); - LogHelper.println (" \x1b[1m-watch\x1b[0m -- Execute the current command when the source changes"); - LogHelper.println (" \x1b[3m(linux)\x1b[0m \x1b[1m-rpi\x1b[0m -- Build for Raspberry Pi"); - LogHelper.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-java\x1b[0m -- Build for Java instead of C++"); - LogHelper.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-nodejs\x1b[0m -- Build for Node.js instead of C++"); - LogHelper.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-cs\x1b[0m -- Build for C# instead of C++"); - LogHelper.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-hl\x1b[0m -- Build for HashLink instead of C++"); - LogHelper.println (" \x1b[3m(windows)\x1b[0m \x1b[1m-winjs\x1b[0m -- Build for WinJS instead of C++ (implies UWP)"); - LogHelper.println (" \x1b[3m(windows)\x1b[0m \x1b[1m-uwp\x1b[0m -- Build for Universal Windows Platform"); - LogHelper.println (" \x1b[3m(html5)\x1b[0m \x1b[1m-electron\x1b[0m -- Target Electron instead of the browser"); + Log.println (""); + Log.println (" " + Log.accentColor + "Experimental Options:" + Log.resetColor); + Log.println (""); + Log.println (" \x1b[1m-watch\x1b[0m -- Execute the current command when the source changes"); + Log.println (" \x1b[3m(linux)\x1b[0m \x1b[1m-rpi\x1b[0m -- Build for Raspberry Pi"); + Log.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-java\x1b[0m -- Build for Java instead of C++"); + Log.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-nodejs\x1b[0m -- Build for Node.js instead of C++"); + Log.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-cs\x1b[0m -- Build for C# instead of C++"); + Log.println (" \x1b[3m(windows|mac|linux)\x1b[0m \x1b[1m-hl\x1b[0m -- Build for HashLink instead of C++"); + Log.println (" \x1b[3m(windows)\x1b[0m \x1b[1m-winjs\x1b[0m -- Build for WinJS instead of C++ (implies UWP)"); + Log.println (" \x1b[3m(windows)\x1b[0m \x1b[1m-uwp\x1b[0m -- Build for Universal Windows Platform"); + Log.println (" \x1b[3m(html5)\x1b[0m \x1b[1m-electron\x1b[0m -- Target Electron instead of the browser"); if (command != "run" && command != "trace") { - LogHelper.println (""); - LogHelper.println (" " + LogHelper.accentColor + "Project Overrides:" + LogHelper.resetColor); - LogHelper.println (""); - LogHelper.println (" \x1b[1m--app-\x1b[0;3moption=value\x1b[0m -- Override a project setting"); - LogHelper.println (" \x1b[1m--meta-\x1b[0;3moption=value\x1b[0m -- Override a project setting"); - LogHelper.println (" \x1b[1m--window-\x1b[0;3moption=value\x1b[0m -- Override a project setting"); - LogHelper.println (" \x1b[1m--dependency\x1b[0;3m=value\x1b[0m -- Add an additional value"); - LogHelper.println (" \x1b[1m--haxedef\x1b[0;3m=value\x1b[0m -- Add an additional value"); - LogHelper.println (" \x1b[1m--haxeflag\x1b[0;3m=value\x1b[0m -- Add an additional value"); - LogHelper.println (" \x1b[1m--haxelib\x1b[0;3m=value\x1b[0m -- Add an additional value"); - LogHelper.println (" \x1b[1m--haxelib-\x1b[0;3mname=value\x1b[0m -- Override the path to a haxelib"); - LogHelper.println (" \x1b[1m--source\x1b[0;3m=value\x1b[0m -- Add an additional value"); - LogHelper.println (" \x1b[1m--certificate-\x1b[0;3moption=value\x1b[0m -- Override a project setting"); + Log.println (""); + Log.println (" " + Log.accentColor + "Project Overrides:" + Log.resetColor); + Log.println (""); + Log.println (" \x1b[1m--app-\x1b[0;3moption=value\x1b[0m -- Override a project setting"); + Log.println (" \x1b[1m--meta-\x1b[0;3moption=value\x1b[0m -- Override a project setting"); + Log.println (" \x1b[1m--window-\x1b[0;3moption=value\x1b[0m -- Override a project setting"); + Log.println (" \x1b[1m--dependency\x1b[0;3m=value\x1b[0m -- Add an additional value"); + Log.println (" \x1b[1m--haxedef\x1b[0;3m=value\x1b[0m -- Add an additional value"); + Log.println (" \x1b[1m--haxeflag\x1b[0;3m=value\x1b[0m -- Add an additional value"); + Log.println (" \x1b[1m--haxelib\x1b[0;3m=value\x1b[0m -- Add an additional value"); + Log.println (" \x1b[1m--haxelib-\x1b[0;3mname=value\x1b[0m -- Override the path to a haxelib"); + Log.println (" \x1b[1m--source\x1b[0;3m=value\x1b[0m -- Add an additional value"); + Log.println (" \x1b[1m--certificate-\x1b[0;3moption=value\x1b[0m -- Override a project setting"); } @@ -1176,50 +1179,50 @@ class CommandLineTools { // var out = ""; // for (i in 0...80) out += "-"; - // LogHelper.println (out); + // Log.println (out); - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { - LogHelper.println (""); + Log.println (""); } if (targetFlags.exists ("openfl")) { - LogHelper.println ("\x1b[37m .d88 88b. \x1b[0m\x1b[1;36m888888b 888 \x1b[0m"); - LogHelper.println ("\x1b[37md88P\" \"Y88b \x1b[0m\x1b[1;36m888 888 \x1b[0m"); - LogHelper.println ("\x1b[37m888 888 \x1b[0m\x1b[1;36m888 888 \x1b[0m"); - LogHelper.println ("\x1b[37m888 888 88888b. .d88b. 88888b. \x1b[0m\x1b[1;36m8888888 888 \x1b[0m"); - LogHelper.println ("\x1b[37m888 888 888 \"88b d8P Y8b 888 \"88b \x1b[0m\x1b[1;36m888 888 \x1b[0m"); - LogHelper.println ("\x1b[37m888 888 888 888 88888888 888 888 \x1b[0m\x1b[1;36m888 888 \x1b[0m"); - LogHelper.println ("\x1b[37mY88b. .d88P 888 d88P Y8b. 888 888 \x1b[0m\x1b[1;36m888 888 \x1b[0m"); - LogHelper.println ("\x1b[37m \"Y88 88P\" 88888P\" \"Y8888 888 888 \x1b[0m\x1b[1;36m888 \"Y888P \x1b[0m"); - LogHelper.println ("\x1b[37m 888 "); - LogHelper.println ("\x1b[37m 888 \x1b[0m"); + Log.println ("\x1b[37m .d88 88b. \x1b[0m\x1b[1;36m888888b 888 \x1b[0m"); + Log.println ("\x1b[37md88P\" \"Y88b \x1b[0m\x1b[1;36m888 888 \x1b[0m"); + Log.println ("\x1b[37m888 888 \x1b[0m\x1b[1;36m888 888 \x1b[0m"); + Log.println ("\x1b[37m888 888 88888b. .d88b. 88888b. \x1b[0m\x1b[1;36m8888888 888 \x1b[0m"); + Log.println ("\x1b[37m888 888 888 \"88b d8P Y8b 888 \"88b \x1b[0m\x1b[1;36m888 888 \x1b[0m"); + Log.println ("\x1b[37m888 888 888 888 88888888 888 888 \x1b[0m\x1b[1;36m888 888 \x1b[0m"); + Log.println ("\x1b[37mY88b. .d88P 888 d88P Y8b. 888 888 \x1b[0m\x1b[1;36m888 888 \x1b[0m"); + Log.println ("\x1b[37m \"Y88 88P\" 88888P\" \"Y8888 888 888 \x1b[0m\x1b[1;36m888 \"Y888P \x1b[0m"); + Log.println ("\x1b[37m 888 "); + Log.println ("\x1b[37m 888 \x1b[0m"); - LogHelper.println (""); - LogHelper.println ("\x1b[1mOpenFL Command-Line Tools\x1b[0;1m (" + getToolsVersion () + ")\x1b[0m"); + Log.println (""); + Log.println ("\x1b[1mOpenFL Command-Line Tools\x1b[0;1m (" + getToolsVersion () + ")\x1b[0m"); } else { - LogHelper.println ("\x1b[32m_\x1b[1m/\\\\\\\\\\\\\x1b[0m\x1b[32m______________________________________________\x1b[0m"); - LogHelper.println ("\x1b[32m_\x1b[1m\\////\\\\\\\x1b[0m\x1b[32m______________________________________________\x1b[0m"); - LogHelper.println ("\x1b[32m_____\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_____\x1b[1m/\\\\\\\x1b[0m\x1b[32m_____________________________________\x1b[0m"); - LogHelper.println ("\x1b[32m______\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m____\x1b[1m\\///\x1b[0m\x1b[32m_____\x1b[1m/\\\\\\\\\\\x1b[0m\x1b[32m__\x1b[1m/\\\\\\\\\\\x1b[0m\x1b[32m_______\x1b[1m/\\\\\\\\\\\\\\\\\x1b[0m\x1b[32m___\x1b[0m"); - LogHelper.println ("\x1b[32m_______\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_____\x1b[1m/\\\\\\\x1b[0m\x1b[32m__\x1b[1m/\\\\\\///\\\\\\\\\\///\\\\\\\x1b[0m\x1b[32m___\x1b[1m/\\\\\\/////\\\\\\\x1b[0m\x1b[32m__\x1b[0m"); - LogHelper.println ("\x1b[32m________\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m____\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\//\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m/\\\\\\\\\\\\\\\\\\\\\\\x1b[0m\x1b[32m___\x1b[0m"); - LogHelper.println ("\x1b[32m_________\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m____\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\//\\\\///////\x1b[0m\x1b[32m____\x1b[0m"); - LogHelper.println ("\x1b[32m________\x1b[1m/\\\\\\\\\\\\\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\//\\\\\\\\\\\\\\\\\\\\\x1b[0m\x1b[32m__\x1b[0m"); - LogHelper.println ("\x1b[32m________\x1b[1m\\/////////\x1b[0m\x1b[32m__\x1b[1m\\///\x1b[0m\x1b[32m__\x1b[1m\\///\x1b[0m\x1b[32m___\x1b[1m\\///\x1b[0m\x1b[32m___\x1b[1m\\///\x1b[0m\x1b[32m____\x1b[1m\\//////////\x1b[0m\x1b[32m___\x1b[0m"); + Log.println ("\x1b[32m_\x1b[1m/\\\\\\\\\\\\\x1b[0m\x1b[32m______________________________________________\x1b[0m"); + Log.println ("\x1b[32m_\x1b[1m\\////\\\\\\\x1b[0m\x1b[32m______________________________________________\x1b[0m"); + Log.println ("\x1b[32m_____\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_____\x1b[1m/\\\\\\\x1b[0m\x1b[32m_____________________________________\x1b[0m"); + Log.println ("\x1b[32m______\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m____\x1b[1m\\///\x1b[0m\x1b[32m_____\x1b[1m/\\\\\\\\\\\x1b[0m\x1b[32m__\x1b[1m/\\\\\\\\\\\x1b[0m\x1b[32m_______\x1b[1m/\\\\\\\\\\\\\\\\\x1b[0m\x1b[32m___\x1b[0m"); + Log.println ("\x1b[32m_______\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_____\x1b[1m/\\\\\\\x1b[0m\x1b[32m__\x1b[1m/\\\\\\///\\\\\\\\\\///\\\\\\\x1b[0m\x1b[32m___\x1b[1m/\\\\\\/////\\\\\\\x1b[0m\x1b[32m__\x1b[0m"); + Log.println ("\x1b[32m________\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m____\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\//\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m/\\\\\\\\\\\\\\\\\\\\\\\x1b[0m\x1b[32m___\x1b[0m"); + Log.println ("\x1b[32m_________\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m____\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\//\\\\///////\x1b[0m\x1b[32m____\x1b[0m"); + Log.println ("\x1b[32m________\x1b[1m/\\\\\\\\\\\\\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m_\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\/\\\\\\\x1b[0m\x1b[32m__\x1b[1m\\//\\\\\\\\\\\\\\\\\\\\\x1b[0m\x1b[32m__\x1b[0m"); + Log.println ("\x1b[32m________\x1b[1m\\/////////\x1b[0m\x1b[32m__\x1b[1m\\///\x1b[0m\x1b[32m__\x1b[1m\\///\x1b[0m\x1b[32m___\x1b[1m\\///\x1b[0m\x1b[32m___\x1b[1m\\///\x1b[0m\x1b[32m____\x1b[1m\\//////////\x1b[0m\x1b[32m___\x1b[0m"); - LogHelper.println (""); - LogHelper.println ("\x1b[1mLime Command-Line Tools\x1b[0;1m (" + getToolsVersion () + ")\x1b[0m"); + Log.println (""); + Log.println ("\x1b[1mLime Command-Line Tools\x1b[0;1m (" + getToolsVersion () + ")\x1b[0m"); } if (showHint) { - LogHelper.println ("Use \x1b[3m" + commandName + " setup\x1b[0m to configure platforms or \x1b[3m" + commandName + " help\x1b[0m for more commands"); + Log.println ("Use \x1b[3m" + commandName + " setup\x1b[0m to configure platforms or \x1b[3m" + commandName + " help\x1b[0m for more commands"); } @@ -1405,12 +1408,12 @@ class CommandLineTools { private function getBuildNumber_GIT (project:Project, increment:Bool = true):String { - var cache = LogHelper.mute; - LogHelper.mute = true; + var cache = Log.mute; + Log.mute = true; var output = ProcessHelper.runProcess ("", "git", [ "rev-list", "HEAD", "--count" ], true, true, true); - LogHelper.mute = cache; + Log.mute = cache; if (output != null) { @@ -1445,12 +1448,12 @@ class CommandLineTools { private function getBuildNumber_SVN (project:Project, increment:Bool = true):String { - var cache = LogHelper.mute; - LogHelper.mute = true; + var cache = Log.mute; + Log.mute = true; var output = ProcessHelper.runProcess ("", "svn", [ "info" ], true, true, true); - LogHelper.mute = cache; + Log.mute = cache; if (output != null) { @@ -1509,7 +1512,7 @@ class CommandLineTools { private function initializeProject (project:Project = null, targetName:String = ""):Project { - LogHelper.info ("", LogHelper.accentColor + "Initializing project..." + LogHelper.resetColor); + Log.info ("", Log.accentColor + "Initializing project..." + Log.resetColor); var projectFile = ""; @@ -1551,12 +1554,12 @@ class CommandLineTools { if (projectFile == "") { - LogHelper.error ("You must have a \"project.xml\" file or specify another valid project file when using the '" + command + "' command"); + Log.error ("You must have a \"project.xml\" file or specify another valid project file when using the '" + command + "' command"); return null; } else { - LogHelper.info ("", LogHelper.accentColor + "Using project file: " + projectFile + LogHelper.resetColor); + Log.info ("", Log.accentColor + "Using project file: " + projectFile + Log.resetColor); } @@ -1586,7 +1589,7 @@ class CommandLineTools { if (!StringTools.startsWith (toolsPath, limePath)) { - LogHelper.info ("", LogHelper.accentColor + "Requesting alternate tools from .haxelib repository...\x1b[0m\n\n"); + Log.info ("", Log.accentColor + "Requesting alternate tools from .haxelib repository...\x1b[0m\n\n"); var args = Sys.args (); args.pop (); @@ -1643,38 +1646,38 @@ class CommandLineTools { } - var target = null; + var target:Platform = null; switch (targetName) { case "cpp": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("cpp", ""); case "neko": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("neko", ""); case "hl": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("hl", ""); case "java": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("java", ""); case "nodejs": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("nodejs", ""); case "cs": - target = PlatformHelper.hostPlatform; + target = cast PlatformHelper.hostPlatform; targetFlags.set ("cs", ""); case "iphone", "iphoneos": @@ -1781,14 +1784,14 @@ class CommandLineTools { } - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { if (environment.get ("JAVA_HOME") != null) { var javaPath = PathHelper.combine (environment.get ("JAVA_HOME"), "bin"); var value; - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { value = javaPath + ";" + Sys.getEnv ("PATH"); @@ -1827,7 +1830,7 @@ class CommandLineTools { if (!environment.exists ("HAXE_STD_PATH")) { - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { environment.set ("HAXE_STD_PATH", "C:\\HaxeToolkit\\haxe\\std\\"); @@ -1879,7 +1882,7 @@ class CommandLineTools { } else { - LogHelper.error ("Could not process \"" + projectFile + "\""); + Log.error ("Could not process \"" + projectFile + "\""); return null; } @@ -1895,7 +1898,7 @@ class CommandLineTools { var limePath = HaxelibHelper.getPath (new Haxelib ("lime"), true, true); Sys.setCwd (workingDirectory); - LogHelper.info ("", LogHelper.accentColor + "Requesting alternate tools from custom haxelib path...\x1b[0m\n\n"); + Log.info ("", Log.accentColor + "Requesting alternate tools from custom haxelib path...\x1b[0m\n\n"); var args = Sys.args (); args.pop (); @@ -1914,7 +1917,7 @@ class CommandLineTools { if (project == null || (command != "rebuild" && project.sources.length == 0 && !FileSystem.exists (project.app.main + ".hx"))) { - LogHelper.error ("You must have a \"project.xml\" file or specify another valid project file when using the '" + command + "' command"); + Log.error ("You must have a \"project.xml\" file or specify another valid project file when using the '" + command + "' command"); return null; } @@ -1961,7 +1964,7 @@ class CommandLineTools { } - LogHelper.info ("", LogHelper.accentColor + "Requesting tools version " + getToolsVersion (haxelib.version) + "...\x1b[0m\n\n"); + Log.info ("", Log.accentColor + "Requesting tools version " + getToolsVersion (haxelib.version) + "...\x1b[0m\n\n"); HaxelibHelper.pathOverrides.remove ("lime"); var path = HaxelibHelper.getPath (haxelib); @@ -1991,7 +1994,7 @@ class CommandLineTools { if (Std.string (version) != Std.string (HaxelibHelper.getVersion (haxelib))) { - LogHelper.warn ("", LogHelper.accentColor + "Could not switch to requested tools version\x1b[0m"); + Log.warn ("", Log.accentColor + "Could not switch to requested tools version\x1b[0m"); } @@ -2086,7 +2089,7 @@ class CommandLineTools { private function platformSetup ():Void { - LogHelper.info ("", LogHelper.accentColor + "Running command: SETUP" + LogHelper.resetColor); + Log.info ("", Log.accentColor + "Running command: SETUP" + Log.resetColor); if (words.length == 0) { @@ -2098,7 +2101,7 @@ class CommandLineTools { } else { - LogHelper.error ("Incorrect number of arguments for command 'setup'"); + Log.error ("Incorrect number of arguments for command 'setup'"); return; } @@ -2169,7 +2172,7 @@ class CommandLineTools { } else { - LogHelper.error ("Could not run Lime tools from this directory"); + Log.error ("Could not run Lime tools from this directory"); } @@ -2428,13 +2431,13 @@ class CommandLineTools { if (command != "display") { - LogHelper.verbose = true; + Log.verbose = true; } } else if (argument == "-force-verbose") { - LogHelper.verbose = true; + Log.verbose = true; } else if (argument == "-dryrun") { @@ -2450,7 +2453,7 @@ class CommandLineTools { } else if (argument == "-nocolor") { - LogHelper.enableColor = false; + Log.enableColor = false; } @@ -2481,13 +2484,13 @@ class CommandLineTools { var project = initializeProject (null, "firefox"); - LogHelper.info ("", LogHelper.accentColor + "Using publishing target: FIREFOX MARKETPLACE" + LogHelper.resetColor); + Log.info ("", Log.accentColor + "Using publishing target: FIREFOX MARKETPLACE" + Log.resetColor); //if (FirefoxMarketplace.isValid (project)) { // //buildProject (project, "build"); // - //LogHelper.info ("", "\n" + LogHelper.accentColor + "Running command: PUBLISH" + LogHelper.resetColor); + //Log.info ("", "\n" + Log.accentColor + "Running command: PUBLISH" + Log.resetColor); // //FirefoxMarketplace.publish (project); // @@ -2502,12 +2505,12 @@ class CommandLineTools { if ((words.length < 1 && command != "upgrade") || words.length > 1) { - LogHelper.error ("Incorrect number of arguments for command '" + command + "'"); + Log.error ("Incorrect number of arguments for command '" + command + "'"); return; } - LogHelper.info ("", LogHelper.accentColor + "Running command: " + command.toUpperCase () + LogHelper.resetColor); + Log.info ("", Log.accentColor + "Running command: " + command.toUpperCase () + Log.resetColor); var name = defaultLibrary; @@ -2553,7 +2556,7 @@ class CommandLineTools { } else { - LogHelper.warn ("\"" + haxelib.name + "\" is not a valid haxelib, or has not been installed"); + Log.warn ("\"" + haxelib.name + "\" is not a valid haxelib, or has not been installed"); } diff --git a/tools/RunScript.hx b/tools/RunScript.hx index d9a190720..4eaa3ebe3 100644 --- a/tools/RunScript.hx +++ b/tools/RunScript.hx @@ -4,255 +4,255 @@ package; import haxe.io.Path; import hxp.helpers.FileHelper; import hxp.helpers.HaxelibHelper; -import hxp.helpers.LogHelper; +import hxp.helpers.Log; import hxp.helpers.PathHelper; import hxp.helpers.PlatformHelper; import hxp.helpers.ProcessHelper; -import hxp.project.Haxelib; +import lime.tools.Project.Haxelib; import sys.io.File; import sys.io.Process; import sys.FileSystem; class RunScript { - - + + private static function rebuildTools (rebuildBinaries = true):Void { - + var limeDirectory = HaxelibHelper.getPath (new Haxelib ("lime"), true); var toolsDirectory = PathHelper.combine (limeDirectory, "tools"); - + if (!FileSystem.exists (toolsDirectory)) { - + toolsDirectory = PathHelper.combine (limeDirectory, "../tools"); - + } - + /*var extendedToolsDirectory = HaxelibHelper.getPath (new Haxelib ("lime-extended"), false); - + if (extendedToolsDirectory != null && extendedToolsDirectory != "") { - + var buildScript = File.getContent (PathHelper.combine (extendedToolsDirectory, "tools.hxml")); buildScript = StringTools.replace (buildScript, "\r\n", "\n"); buildScript = StringTools.replace (buildScript, "\n", " "); - + ProcessHelper.runCommand (toolsDirectory, "haxe", buildScript.split (" ")); - + } else {*/ - + ProcessHelper.runCommand (toolsDirectory, "haxe", [ "tools.hxml" ]); - + //} - + if (!rebuildBinaries) return; - + var platforms = [ "Windows", "Mac", "Mac64", "Linux", "Linux64" ]; - + for (platform in platforms) { - + var source = PathHelper.combine (limeDirectory, "ndll/" + platform + "/lime.ndll"); //var target = PathHelper.combine (toolsDirectory, "ndll/" + platform + "/lime.ndll"); - + if (!FileSystem.exists (source)) { - + var args = [ "tools/tools.n", "rebuild", "lime", "-release", "-nocffi" ]; - - if (LogHelper.verbose) { - + + if (Log.verbose) { + args.push ("-verbose"); - + } - - if (!LogHelper.enableColor) { - + + if (!Log.enableColor) { + args.push ("-nocolor"); - + } - + switch (platform) { - + case "Windows": - + if (PlatformHelper.hostPlatform == WINDOWS) { - + ProcessHelper.runCommand (limeDirectory, "neko", args.concat ([ "windows", toolsDirectory ])); - + } - + case "Mac", "Mac64": - + if (PlatformHelper.hostPlatform == MAC) { - + ProcessHelper.runCommand (limeDirectory, "neko", args.concat ([ "mac", toolsDirectory ])); - + } - + case "Linux": - + if (PlatformHelper.hostPlatform == LINUX && PlatformHelper.hostArchitecture != X64) { - + ProcessHelper.runCommand (limeDirectory, "neko", args.concat ([ "linux", "-32", toolsDirectory ])); - + } - + case "Linux64": - + if (PlatformHelper.hostPlatform == LINUX && PlatformHelper.hostArchitecture == X64) { - + ProcessHelper.runCommand (limeDirectory, "neko", args.concat ([ "linux", "-64", toolsDirectory ])); - + } - + } - + } - + if (!FileSystem.exists (source)) { - - if (LogHelper.verbose) { - - LogHelper.warn ("", "Source path \"" + source + "\" does not exist"); - + + if (Log.verbose) { + + Log.warn ("", "Source path \"" + source + "\" does not exist"); + } - + } else { - + //FileHelper.copyIfNewer (source, target); - + } - + } - + } - - + + public static function runCommand (path:String, command:String, args:Array, throwErrors:Bool = true):Int { - + var oldPath:String = ""; - + if (path != null && path != "") { - + oldPath = Sys.getCwd (); - + try { - + Sys.setCwd (path); - + } catch (e:Dynamic) { - - LogHelper.error ("Cannot set current working directory to \"" + path + "\""); - + + Log.error ("Cannot set current working directory to \"" + path + "\""); + } - + } - + var result:Dynamic = Sys.command (command, args); - + if (oldPath != "") { - + Sys.setCwd (oldPath); - + } - + if (throwErrors && result != 0) { - + Sys.exit (1); - + } - + return result; - + } - - + + public static function main () { - + var args = Sys.args (); - + if (args.length > 2 && args[0] == "rebuild" && args[1] == "tools") { - + var lastArgument = new Path (args[args.length - 1]).toString (); var cacheDirectory = Sys.getCwd (); - + if (((StringTools.endsWith (lastArgument, "/") && lastArgument != "/") || StringTools.endsWith (lastArgument, "\\")) && !StringTools.endsWith (lastArgument, ":\\")) { - + lastArgument = lastArgument.substr (0, lastArgument.length - 1); - + } - + if (FileSystem.exists (lastArgument) && FileSystem.isDirectory (lastArgument)) { - + Sys.setCwd (lastArgument); - + } - + HaxelibHelper.workingDirectory = Sys.getCwd (); var rebuildBinaries = true; - + for (arg in args) { - + var equals = arg.indexOf ("="); - + if (equals > -1 && StringTools.startsWith (arg, "--")) { - + var argValue = arg.substr (equals + 1); var field = arg.substr (2, equals - 2); - + if (StringTools.startsWith (field, "haxelib-")) { - + var name = field.substr (8); HaxelibHelper.pathOverrides.set (name, PathHelper.tryFullPath (argValue)); - + } - + } else if (StringTools.startsWith (arg, "-")) { - + switch (arg) { - + case "-v", "-verbose": - - LogHelper.verbose = true; - + + Log.verbose = true; + case "-nocolor": - - LogHelper.enableColor = false; - + + Log.enableColor = false; + case "-nocffi": - + rebuildBinaries = false; - + default: - + } - + } - + } - + rebuildTools (rebuildBinaries); - + if (args.indexOf ("-openfl") > -1) { - + Sys.setCwd (cacheDirectory); - + } else { - + Sys.exit (0); - + } - + } - + if (!FileSystem.exists ("tools/tools.n") || args.indexOf ("-rebuild") > -1) { - + rebuildTools (); - + } - + var args = [ "tools/tools.n" ].concat (args); Sys.exit (runCommand ("", "neko", args)); - + } - - + + } \ No newline at end of file diff --git a/tools/SVGExport.hx b/tools/SVGExport.hx index e5cb65777..7dc05fd00 100644 --- a/tools/SVGExport.hx +++ b/tools/SVGExport.hx @@ -3,10 +3,10 @@ package; import format.SVG; import haxe.io.Path; -import hxp.helpers.LogHelper; +import hxp.helpers.Log; import hxp.helpers.PathHelper; import hxp.helpers.PlatformHelper; -import hxp.project.Architecture; +import lime.tools.Project.Architecture; import openfl.display.Bitmap; import openfl.display.BitmapData; import openfl.display.PNGEncoderOptions; @@ -18,171 +18,171 @@ import sys.FileSystem; class SVGExport { - - + + #if (neko && (haxe_210 || haxe3)) public static function __init__ () { - + var haxePath = Sys.getEnv ("HAXEPATH"); var command = (haxePath != null && haxePath != "") ? haxePath + "/haxelib" : "haxelib"; - + var path = ""; - + if (FileSystem.exists ("svg.n")) { - + path = PathHelper.combine (Sys.getCwd (), "../ndll/"); - + } - + if (path == "") { - + var process = new Process ("haxelib", [ "path", "lime" ]); - + try { - + while (true) { - + var line = StringTools.trim (process.stdout.readLine ()); - + if (StringTools.startsWith (line, "-L ")) { - + path = StringTools.trim (line.substr (2)); break; - + } - + } - + } catch (e:Dynamic) {} - + process.close (); - + } - + switch (PlatformHelper.hostPlatform) { - + case WINDOWS: - + untyped $loader.path = $array (path + "Windows/", $loader.path); - + case MAC: - + untyped $loader.path = $array (path + "Mac/", $loader.path); untyped $loader.path = $array (path + "Mac64/", $loader.path); - + case LINUX: - + var arguments = Sys.args (); var raspberryPi = false; - + for (argument in arguments) { - + if (argument == "-rpi") raspberryPi = true; - + } - + if (raspberryPi) { - + untyped $loader.path = $array (path + "RPi/", $loader.path); - - } else if (PlatformHelper.hostArchitecture == Architecture.X64) { - + + } else if (PlatformHelper.hostArchitecture == X64) { + untyped $loader.path = $array (path + "Linux64/", $loader.path); - + } else { - + untyped $loader.path = $array (path + "Linux/", $loader.path); - + } - + default: - + } - + } #end - - + + public static function main () { - + var arguments = Sys.args (); - + /*if (arguments.length > 0) { - - // When the command-line tools are called from haxelib, + + // When the command-line tools are called from haxelib, // the last argument is the project directory and the - // path SWF is the current working directory - + // path SWF is the current working directory + var lastArgument = ""; - + for (i in 0...arguments.length) { - + lastArgument = arguments.pop (); if (lastArgument.length > 0) break; - + } - + lastArgument = new Path (lastArgument).toString (); - + if (((StringTools.endsWith (lastArgument, "/") && lastArgument != "/") || StringTools.endsWith (lastArgument, "\\")) && !StringTools.endsWith (lastArgument, ":\\")) { - + lastArgument = lastArgument.substr (0, lastArgument.length - 1); - + } - + if (FileSystem.exists (lastArgument) && FileSystem.isDirectory (lastArgument)) { - + Sys.setCwd (lastArgument); - + } - + }*/ - + var words = new Array (); - + for (arg in arguments) { - + if (arg == "-verbose") { - - LogHelper.verbose = true; - + + Log.verbose = true; + } else { - + words.push (arg); - + } - + } - + if (words.length > 4 && words[0] == "process") { - + try { - + var inputPath = words[1]; var width = Std.parseInt (words[2]); var height = Std.parseInt (words[3]); var outputPath = words[4]; - + var svg = new SVG (File.getContent (inputPath)); var backgroundColor = 0x00FFFFFF; - + var shape = new Shape (); svg.render (shape.graphics, 0, 0, width, height); - + var bitmapData = new BitmapData (width, height, true, backgroundColor); bitmapData.draw (shape); - + File.saveBytes (outputPath, bitmapData.encode (bitmapData.rect, new PNGEncoderOptions ())); - + } catch (e:Dynamic) { - - LogHelper.error (e); - + + Log.error (e); + } - + } - + } - - + + } \ No newline at end of file diff --git a/tools/platforms/AIRPlatform.hx b/tools/platforms/AIRPlatform.hx index 6ce812e74..0c26cc3ef 100644 --- a/tools/platforms/AIRPlatform.hx +++ b/tools/platforms/AIRPlatform.hx @@ -3,39 +3,22 @@ package; import haxe.io.Path; import haxe.Template; -#if (hxp > "1.0.0") -import hxp.AIRHelper; -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.DeploymentHelper; +import lime.tools.AIRHelper; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.DeploymentHelper; import hxp.FileHelper; -import hxp.FlashHelper; -import hxp.Icon; -import hxp.IconHelper; -import hxp.LogHelper; +import lime.tools.FlashHelper; +import lime.tools.Icon; +import lime.tools.IconHelper; +import hxp.Log; import hxp.PathHelper; -import hxp.Platform; +import lime.tools.Platform; import hxp.PlatformHelper; -import hxp.PlatformType; -import hxp.Project; +import lime.tools.PlatformType; +import lime.tools.Project; +import lime.tools.ProjectHelper; import hxp.ZipHelper; -#else -import hxp.project.AssetType; -import hxp.project.HXProject in Project; -import hxp.project.Icon; -import hxp.project.Platform; -import hxp.project.PlatformType; -import hxp.helpers.AIRHelper; -import hxp.helpers.AssetHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.FileHelper; -import hxp.helpers.FlashHelper; -import hxp.helpers.IconHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.PlatformHelper; -import hxp.helpers.LogHelper; -import hxp.helpers.ZipHelper; -#end import sys.io.File; import sys.FileSystem; @@ -77,7 +60,7 @@ class AIRPlatform extends FlashPlatform { } else { - targetPlatform = PlatformHelper.hostPlatform; + targetPlatform = cast PlatformHelper.hostPlatform; targetPlatformType = DESKTOP; } @@ -91,7 +74,7 @@ class AIRPlatform extends FlashPlatform { if (!project.defines.exists ("AIR_SDK")) { - LogHelper.error ("You must define AIR_SDK with the path to your AIR SDK"); + Log.error ("You must define AIR_SDK with the path to your AIR SDK"); } @@ -305,7 +288,7 @@ class AIRPlatform extends FlashPlatform { if (buildNumber.length > 0) { - LogHelper.warn ("Application build number " + buildNumber + buildNumberSplit + " exceeds 9 digits"); + Log.warn ("Application build number " + buildNumber + buildNumberSplit + " exceeds 9 digits"); } @@ -355,9 +338,9 @@ class AIRPlatform extends FlashPlatform { } - FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "air/hxml", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "air/template", targetDirectory, context); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "air/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "air/template", targetDirectory, context); if (embedded) { @@ -400,7 +383,7 @@ class AIRPlatform extends FlashPlatform { var path = PathHelper.combine (destination, asset.targetPath); PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path, context); + AssetHelper.copyAsset (asset, path, context); } diff --git a/tools/platforms/AndroidPlatform.hx b/tools/platforms/AndroidPlatform.hx index 9c06b6882..2c8fdfeae 100644 --- a/tools/platforms/AndroidPlatform.hx +++ b/tools/platforms/AndroidPlatform.hx @@ -3,43 +3,24 @@ package; import haxe.io.Path; import haxe.Template; -#if (hxp > "1.0.0") -import hxp.AndroidHelper; -import hxp.Architecture; +import lime.tools.AndroidHelper; +import lime.tools.Architecture; import hxp.ArrayHelper; -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.CPPHelper; -import hxp.DeploymentHelper; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.CPPHelper; +import lime.tools.DeploymentHelper; import hxp.FileHelper; import hxp.Haxelib; -import hxp.Icon; -import hxp.IconHelper; -import hxp.LogHelper; +import lime.tools.Icon; +import lime.tools.IconHelper; +import hxp.Log; import hxp.PathHelper; -import hxp.PlatformTarget; +import lime.tools.PlatformTarget; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; +import lime.tools.ProjectHelper; import hxp.WatchHelper; -#else -import hxp.helpers.AndroidHelper; -import hxp.helpers.ArrayHelper; -import hxp.helpers.AssetHelper; -import hxp.helpers.CPPHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.FileHelper; -import hxp.helpers.IconHelper; -import hxp.helpers.LogHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.ProcessHelper; -import hxp.helpers.WatchHelper; -import hxp.project.Architecture; -import hxp.project.AssetType; -import hxp.project.Haxelib; -import hxp.project.HXProject in Project; -import hxp.project.Icon; -import hxp.project.PlatformTarget; -#end import sys.io.File; import sys.FileSystem; @@ -60,7 +41,7 @@ class AndroidPlatform extends PlatformTarget { if (!project.environment.exists ("ANDROID_SETUP")) { - LogHelper.error ("You need to run \"lime setup android\" before you can use the Android target"); + Log.error ("You need to run \"lime setup android\" before you can use the Android target"); } @@ -135,7 +116,7 @@ class AndroidPlatform extends PlatformTarget { for (ndll in project.ndlls) { - FileHelper.copyLibrary (project, ndll, "Android", "lib", suffix, path, project.debug, ".so"); + ProjectHelper.copyLibrary (project, ndll, "Android", "lib", suffix, path, project.debug, ".so"); } @@ -317,7 +298,7 @@ class AndroidPlatform extends PlatformTarget { var path = PathHelper.combine (targetDirectory + "/obj/tmp", asset.targetPath); PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path); + AssetHelper.copyAsset (asset, path); asset.sourcePath = path; } @@ -361,7 +342,7 @@ class AndroidPlatform extends PlatformTarget { } - FileHelper.copyAssetIfNewer (asset, targetPath); + AssetHelper.copyAssetIfNewer (asset, targetPath); } @@ -393,7 +374,7 @@ class AndroidPlatform extends PlatformTarget { if (toolsBase != null) command = Reflect.field (toolsBase, "commandName"); - LogHelper.error ("You must define ANDROID_SDK and ANDROID_NDK_ROOT to target Android, please run '" + command + " setup android' first"); + Log.error ("You must define ANDROID_SDK and ANDROID_NDK_ROOT to target Android, please run '" + command + " setup android' first"); Sys.exit (1); } @@ -501,10 +482,10 @@ class AndroidPlatform extends PlatformTarget { } - FileHelper.recursiveSmartCopyTemplate (project, "android/template", destination, context); + ProjectHelper.recursiveSmartCopyTemplate (project, "android/template", destination, context); FileHelper.copyFileTemplate (project.templatePaths, "android/MainActivity.java", packageDirectory + "/MainActivity.java", context); - FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "android/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "android/hxml", targetDirectory + "/haxe", context); for (asset in project.assets) { @@ -512,7 +493,7 @@ class AndroidPlatform extends PlatformTarget { var targetPath = PathHelper.combine (destination, asset.targetPath); PathHelper.mkdir (Path.directory (targetPath)); - FileHelper.copyAsset (asset, targetPath, context); + AssetHelper.copyAsset (asset, targetPath, context); } @@ -523,9 +504,9 @@ class AndroidPlatform extends PlatformTarget { public override function watch ():Void { - var dirs = WatchHelper.processHXML (project, getDisplayHXML ()); - var command = WatchHelper.getCurrentCommand (); - WatchHelper.watch (project, command, dirs); + var dirs = WatchHelper.processHXML (getDisplayHXML (), project.app.path); + var command = ProjectHelper.getCurrentCommand (); + WatchHelper.watch (command, dirs); } diff --git a/tools/platforms/EmscriptenPlatform.hx b/tools/platforms/EmscriptenPlatform.hx index 1a4fde4c6..02700bb34 100644 --- a/tools/platforms/EmscriptenPlatform.hx +++ b/tools/platforms/EmscriptenPlatform.hx @@ -4,33 +4,19 @@ package; import haxe.io.Path; import haxe.Json; import haxe.Template; -#if (hxp > "1.0.0") -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.CPPHelper; -import hxp.DeploymentHelper; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.CPPHelper; +import lime.tools.DeploymentHelper; import hxp.FileHelper; import hxp.Haxelib; -import hxp.HTML5Helper; -import hxp.LogHelper; +import lime.tools.HTML5Helper; +import hxp.Log; import hxp.PathHelper; -import hxp.PlatformTarget; +import lime.tools.PlatformTarget; import hxp.ProcessHelper; -import hxp.Project; -#else -import hxp.helpers.AssetHelper; -import hxp.helpers.CPPHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.FileHelper; -import hxp.helpers.HTML5Helper; -import hxp.helpers.LogHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.ProcessHelper; -import hxp.project.AssetType; -import hxp.project.Haxelib; -import hxp.project.HXProject in Project; -import hxp.project.PlatformTarget; -#end +import lime.tools.Project; +import lime.tools.ProjectHelper; import sys.io.File; import sys.FileSystem; @@ -67,14 +53,14 @@ class EmscriptenPlatform extends PlatformTarget { if (sdkPath == null) { - LogHelper.error ("You must define EMSCRIPTEN_SDK with the path to your Emscripten SDK"); + Log.error ("You must define EMSCRIPTEN_SDK with the path to your Emscripten SDK"); } var hxml = targetDirectory + "/haxe/" + buildType + ".hxml"; var args = [ hxml, "-D", "emscripten", "-D", "webgl", "-D", "static_link"]; - if (LogHelper.verbose) { + if (Log.verbose) { args.push ("-D"); args.push ("verbose"); @@ -197,7 +183,7 @@ class EmscriptenPlatform extends PlatformTarget { } - if (LogHelper.verbose) { + if (Log.verbose) { args.push ("-v"); @@ -311,7 +297,7 @@ class EmscriptenPlatform extends PlatformTarget { var path = PathHelper.combine (targetDirectory + "/obj/tmp", asset.targetPath); PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path); + AssetHelper.copyAsset (asset, path); asset.sourcePath = path; } @@ -360,7 +346,7 @@ class EmscriptenPlatform extends PlatformTarget { //if (asset.type != AssetType.FONT) { PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAssetIfNewer (asset, path); + AssetHelper.copyAssetIfNewer (asset, path); //} @@ -368,10 +354,10 @@ class EmscriptenPlatform extends PlatformTarget { } - FileHelper.recursiveSmartCopyTemplate (project, "emscripten/template", destination, context); - FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "emscripten/hxml", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "emscripten/cpp", targetDirectory + "/obj", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "emscripten/template", destination, context); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "emscripten/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "emscripten/cpp", targetDirectory + "/obj", context); for (asset in project.assets) { @@ -380,7 +366,7 @@ class EmscriptenPlatform extends PlatformTarget { if (asset.type == AssetType.TEMPLATE) { PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path, context); + AssetHelper.copyAsset (asset, path, context); } diff --git a/tools/platforms/FlashPlatform.hx b/tools/platforms/FlashPlatform.hx index 5779852f2..770492781 100644 --- a/tools/platforms/FlashPlatform.hx +++ b/tools/platforms/FlashPlatform.hx @@ -4,39 +4,22 @@ package; import haxe.io.Path; import haxe.Json; import haxe.Template; -#if (hxp > "1.0.0") -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.DeploymentHelper; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.DeploymentHelper; +import lime.tools.ProjectHelper; import hxp.FileHelper; -import hxp.FlashHelper; +import lime.tools.FlashHelper; import hxp.Haxelib; -import hxp.HTML5Helper; -import hxp.LogHelper; +import lime.tools.HTML5Helper; +import hxp.Log; import hxp.PathHelper; -import hxp.Platform; +import lime.tools.Platform; import hxp.PlatformHelper; -import hxp.PlatformTarget; +import lime.tools.PlatformTarget; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; import hxp.WatchHelper; -#else -import hxp.helpers.AssetHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.FileHelper; -import hxp.helpers.FlashHelper; -import hxp.helpers.HTML5Helper; -import hxp.helpers.LogHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.PlatformHelper; -import hxp.helpers.ProcessHelper; -import hxp.helpers.WatchHelper; -import hxp.project.AssetType; -import hxp.project.Haxelib; -import hxp.project.HXProject in Project; -import hxp.project.Platform; -import hxp.project.PlatformTarget; -#end import sys.io.File; import sys.FileSystem; @@ -105,7 +88,7 @@ class FlashPlatform extends PlatformTarget { } - if (LogHelper.verbose) { + if (Log.verbose) { project.haxedefs.set ("verbose", 1); @@ -221,14 +204,14 @@ class FlashPlatform extends PlatformTarget { var context = generateContext (); context.OUTPUT_DIR = targetDirectory; - FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "flash/hxml", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "flash/haxe", targetDirectory + "/haxe", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "flash/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "flash/haxe", targetDirectory + "/haxe", context, true, false); if (project.targetFlags.exists ("web") || project.app.url != "") { PathHelper.mkdir (destination); - FileHelper.recursiveSmartCopyTemplate (project, "flash/templates/web", destination, generateContext ()); + ProjectHelper.recursiveSmartCopyTemplate (project, "flash/templates/web", destination, generateContext ()); } @@ -273,7 +256,7 @@ class FlashPlatform extends PlatformTarget { var path = PathHelper.combine (destination, asset.targetPath); PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path, context); + AssetHelper.copyAsset (asset, path, context); } @@ -301,9 +284,9 @@ class FlashPlatform extends PlatformTarget { public override function watch ():Void { - var dirs = WatchHelper.processHXML (project, getDisplayHXML ()); - var command = WatchHelper.getCurrentCommand (); - WatchHelper.watch (project, command, dirs); + var dirs = WatchHelper.processHXML (getDisplayHXML (), project.app.path); + var command = ProjectHelper.getCurrentCommand (); + WatchHelper.watch (command, dirs); } diff --git a/tools/platforms/HTML5Platform.hx b/tools/platforms/HTML5Platform.hx index fa6625236..30ae39fed 100644 --- a/tools/platforms/HTML5Platform.hx +++ b/tools/platforms/HTML5Platform.hx @@ -6,39 +6,22 @@ import haxe.Template; #if lime import lime.text.Font; #end -#if (hxp > "1.0.0") -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.DeploymentHelper; -import hxp.ElectronHelper; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.DeploymentHelper; +import lime.tools.ElectronHelper; import hxp.FileHelper; -import hxp.HTML5Helper; -import hxp.Icon; -import hxp.IconHelper; -import hxp.LogHelper; -import hxp.ModuleHelper; +import lime.tools.HTML5Helper; +import lime.tools.Icon; +import lime.tools.IconHelper; +import hxp.Log; +import lime.tools.ModuleHelper; +import lime.tools.ProjectHelper; import hxp.PathHelper; -import hxp.PlatformTarget; +import lime.tools.PlatformTarget; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; import hxp.WatchHelper; -#else -import hxp.helpers.AssetHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.ElectronHelper; -import hxp.helpers.FileHelper; -import hxp.helpers.HTML5Helper; -import hxp.helpers.IconHelper; -import hxp.helpers.LogHelper; -import hxp.helpers.ModuleHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.ProcessHelper; -import hxp.helpers.WatchHelper; -import hxp.project.AssetType; -import hxp.project.HXProject in Project; -import hxp.project.Icon; -import hxp.project.PlatformTarget; -#end import sys.io.File; import sys.FileSystem; @@ -255,7 +238,7 @@ class HTML5Platform extends PlatformTarget { if (extension != ".eot" && extension != ".svg") { - LogHelper.warn ("Could not generate *" + extension + " web font for \"" + originalPath + "\""); + Log.warn ("Could not generate *" + extension + " web font for \"" + originalPath + "\""); } @@ -284,7 +267,7 @@ class HTML5Platform extends PlatformTarget { } - if (LogHelper.verbose) { + if (Log.verbose) { project.haxedefs.set ("verbose", 1); @@ -374,7 +357,7 @@ class HTML5Platform extends PlatformTarget { if (/*asset.embed != true &&*/ asset.type != AssetType.FONT) { PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAssetIfNewer (asset, path); + AssetHelper.copyAssetIfNewer (asset, path); } else if (asset.type == AssetType.FONT && useWebfonts) { @@ -453,24 +436,24 @@ class HTML5Platform extends PlatformTarget { } - FileHelper.recursiveSmartCopyTemplate (project, "html5/template", destination, context); + ProjectHelper.recursiveSmartCopyTemplate (project, "html5/template", destination, context); if (project.app.main != null) { - FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "html5/haxe", targetDirectory + "/haxe", context, true, false); - FileHelper.recursiveSmartCopyTemplate (project, "html5/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "html5/haxe", targetDirectory + "/haxe", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "html5/hxml", targetDirectory + "/haxe", context); } if (targetFlags.exists ("electron")) { - FileHelper.recursiveSmartCopyTemplate (project, "electron/template", destination, context); + ProjectHelper.recursiveSmartCopyTemplate (project, "electron/template", destination, context); if (project.app.main != null) { - FileHelper.recursiveSmartCopyTemplate (project, "electron/haxe", targetDirectory + "/haxe", context, true, false); - FileHelper.recursiveSmartCopyTemplate (project, "electron/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "electron/haxe", targetDirectory + "/haxe", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "electron/hxml", targetDirectory + "/haxe", context); } @@ -483,7 +466,7 @@ class HTML5Platform extends PlatformTarget { if (asset.type == AssetType.TEMPLATE) { PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path, context); + AssetHelper.copyAsset (asset, path, context); } @@ -496,9 +479,9 @@ class HTML5Platform extends PlatformTarget { // TODO: Use a custom live reload HTTP server for test/run instead - var dirs = WatchHelper.processHXML (project, getDisplayHXML ()); - var command = WatchHelper.getCurrentCommand (); - WatchHelper.watch (project, command, dirs); + var dirs = WatchHelper.processHXML (getDisplayHXML (), project.app.path); + var command = ProjectHelper.getCurrentCommand (); + WatchHelper.watch (command, dirs); } diff --git a/tools/platforms/IOSPlatform.hx b/tools/platforms/IOSPlatform.hx index ac417bda2..e4cea8c28 100644 --- a/tools/platforms/IOSPlatform.hx +++ b/tools/platforms/IOSPlatform.hx @@ -5,55 +5,30 @@ package; import haxe.io.Path; import haxe.Json; import haxe.Template; -#if (hxp > "1.0.0") -import hxp.Architecture; +import lime.tools.Architecture; import hxp.ArrayHelper; -import hxp.Asset; -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.CPPHelper; -import hxp.DeploymentHelper; +import lime.tools.Asset; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.CPPHelper; +import lime.tools.DeploymentHelper; import hxp.FileHelper; import hxp.Haxelib; -import hxp.Icon; -import hxp.IconHelper; -import hxp.IOSHelper; -import hxp.Keystore; -import hxp.LogHelper; +import lime.tools.Icon; +import lime.tools.IconHelper; +import lime.tools.IOSHelper; +import lime.tools.Keystore; +import hxp.Log; import hxp.NDLL; import hxp.PathHelper; -import hxp.Platform; +import lime.tools.Platform; import hxp.PlatformHelper; -import hxp.PlatformTarget; +import lime.tools.PlatformTarget; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; +import lime.tools.ProjectHelper; import hxp.StringHelper; import hxp.WatchHelper; -#else -import hxp.helpers.ArrayHelper; -import hxp.helpers.AssetHelper; -import hxp.helpers.CPPHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.FileHelper; -import hxp.helpers.IconHelper; -import hxp.helpers.IOSHelper; -import hxp.helpers.LogHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.PlatformHelper; -import hxp.helpers.ProcessHelper; -import hxp.helpers.StringHelper; -import hxp.helpers.WatchHelper; -import hxp.project.Architecture; -import hxp.project.Asset; -import hxp.project.AssetType; -import hxp.project.Haxelib; -import hxp.project.HXProject in Project; -import hxp.project.Icon; -import hxp.project.Keystore; -import hxp.project.NDLL; -import hxp.project.Platform; -import hxp.project.PlatformTarget; -#end #if lime import lime.graphics.Image; #end @@ -75,7 +50,7 @@ class IOSPlatform extends PlatformTarget { public override function build ():Void { - if (project.targetFlags.exists ("xcode") && PlatformHelper.hostPlatform == Platform.MAC) { + if (project.targetFlags.exists ("xcode") && PlatformHelper.hostPlatform == MAC) { ProcessHelper.runCommand ("", "open", [ targetDirectory + "/" + project.app.file + ".xcodeproj" ] ); @@ -499,7 +474,7 @@ class IOSPlatform extends PlatformTarget { var path = PathHelper.combine (targetDirectory + "/" + project.app.file + "/obj/tmp", asset.targetPath); PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path); + AssetHelper.copyAsset (asset, path); asset.sourcePath = path; } @@ -610,7 +585,7 @@ class IOSPlatform extends PlatformTarget { if (!FileSystem.exists (imagePath)) { #if (lime && lime_cffi && !macro) - LogHelper.info ("", " - \x1b[1mGenerating image:\x1b[0m " + imagePath); + Log.info ("", " - \x1b[1mGenerating image:\x1b[0m " + imagePath); var image = new Image (null, 0, 0, size.w, size.h, (0xFF << 24) | (project.window.background & 0xFFFFFF)); var bytes = image.encode (PNG); @@ -631,21 +606,21 @@ class IOSPlatform extends PlatformTarget { // Long deprecated template path - FileHelper.recursiveSmartCopyTemplate (project, "iphone/resources", projectDirectory + "/resources", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "iphone/resources", projectDirectory + "/resources", context, true, false); // New template path - FileHelper.recursiveSmartCopyTemplate (project, "ios/template", targetDirectory, context); + ProjectHelper.recursiveSmartCopyTemplate (project, "ios/template", targetDirectory, context); // Recently deprecated template paths - FileHelper.recursiveSmartCopyTemplate (project, "iphone/PROJ/haxe", projectDirectory + "/haxe", context, true, false); - FileHelper.recursiveSmartCopyTemplate (project, "haxe", projectDirectory + "/haxe", context, true, false); - FileHelper.recursiveSmartCopyTemplate (project, "iphone/PROJ/Classes", projectDirectory + "/Classes", context, true, false); - FileHelper.recursiveSmartCopyTemplate (project, "iphone/PROJ/Images.xcassets", projectDirectory + "/Images.xcassets", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "iphone/PROJ/haxe", projectDirectory + "/haxe", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", projectDirectory + "/haxe", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "iphone/PROJ/Classes", projectDirectory + "/Classes", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "iphone/PROJ/Images.xcassets", projectDirectory + "/Images.xcassets", context, true, false); FileHelper.copyFileTemplate (project.templatePaths, "iphone/PROJ/PROJ-Info.plist", projectDirectory + "/" + project.app.file + "-Info.plist", context, true, false); FileHelper.copyFileTemplate (project.templatePaths, "iphone/PROJ/PROJ-Prefix.pch", projectDirectory + "/" + project.app.file + "-Prefix.pch", context, true, false); - FileHelper.recursiveSmartCopyTemplate (project, "iphone/PROJ.xcodeproj", targetDirectory + "/" + project.app.file + ".xcodeproj", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "iphone/PROJ.xcodeproj", targetDirectory + "/" + project.app.file + ".xcodeproj", context, true, false); PathHelper.mkdir (projectDirectory + "/lib"); @@ -733,7 +708,7 @@ class IOSPlatform extends PlatformTarget { //var sourceAssetPath:String = projectDirectory + "haxe/" + asset.sourcePath; PathHelper.mkdir (Path.directory (targetPath)); - FileHelper.copyAssetIfNewer (asset, targetPath); + AssetHelper.copyAssetIfNewer (asset, targetPath); //PathHelper.mkdir (Path.directory (sourceAssetPath)); //FileHelper.linkFile (flatAssetPath, sourceAssetPath, true, true); @@ -743,13 +718,13 @@ class IOSPlatform extends PlatformTarget { var targetPath = PathHelper.combine (projectDirectory, asset.targetPath); PathHelper.mkdir (Path.directory (targetPath)); - FileHelper.copyAsset (asset, targetPath, context); + AssetHelper.copyAsset (asset, targetPath, context); } } - if (project.targetFlags.exists ("xcode") && PlatformHelper.hostPlatform == Platform.MAC && command == "update") { + if (project.targetFlags.exists ("xcode") && PlatformHelper.hostPlatform == MAC && command == "update") { ProcessHelper.runCommand ("", "open", [ targetDirectory + "/" + project.app.file + ".xcodeproj" ] ); @@ -781,9 +756,9 @@ class IOSPlatform extends PlatformTarget { public override function watch ():Void { - var dirs = WatchHelper.processHXML (project, getDisplayHXML ()); - var command = WatchHelper.getCurrentCommand (); - WatchHelper.watch (project, command, dirs); + var dirs = WatchHelper.processHXML (getDisplayHXML (), project.app.path); + var command = ProjectHelper.getCurrentCommand (); + WatchHelper.watch (command, dirs); } diff --git a/tools/platforms/LinuxPlatform.hx b/tools/platforms/LinuxPlatform.hx index 97038a38b..f1b487cd5 100644 --- a/tools/platforms/LinuxPlatform.hx +++ b/tools/platforms/LinuxPlatform.hx @@ -3,45 +3,25 @@ package; import haxe.io.Path; import haxe.Template; -#if (hxp > "1.0.0") -import hxp.Architecture; -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.CPPHelper; -import hxp.DeploymentHelper; +import lime.tools.Architecture; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.CPPHelper; +import lime.tools.DeploymentHelper; import hxp.FileHelper; import hxp.Haxelib; -import hxp.JavaHelper; -import hxp.LogHelper; -import hxp.NekoHelper; -import hxp.NodeJSHelper; +import lime.tools.JavaHelper; +import hxp.Log; +import lime.tools.NekoHelper; +import lime.tools.NodeJSHelper; import hxp.PathHelper; -import hxp.Platform; +import lime.tools.Platform; import hxp.PlatformHelper; -import hxp.PlatformTarget; +import lime.tools.PlatformTarget; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; +import lime.tools.ProjectHelper; import hxp.WatchHelper; -#else -import hxp.helpers.AssetHelper; -import hxp.helpers.CPPHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.FileHelper; -import hxp.helpers.JavaHelper; -import hxp.helpers.LogHelper; -import hxp.helpers.NekoHelper; -import hxp.helpers.NodeJSHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.PlatformHelper; -import hxp.helpers.ProcessHelper; -import hxp.helpers.WatchHelper; -import hxp.project.AssetType; -import hxp.project.Architecture; -import hxp.project.Haxelib; -import hxp.project.HXProject in Project; -import hxp.project.Platform; -import hxp.project.PlatformTarget; -#end import sys.io.File; import sys.io.Process; import sys.FileSystem; @@ -82,7 +62,7 @@ class LinuxPlatform extends PlatformTarget { } - if (project.targetFlags.exists ("neko") || project.target != PlatformHelper.hostPlatform) { + if (project.targetFlags.exists ("neko") || project.target != cast PlatformHelper.hostPlatform) { targetType = "neko"; @@ -126,11 +106,11 @@ class LinuxPlatform extends PlatformTarget { if (isRaspberryPi) { - FileHelper.copyLibrary (project, ndll, "RPi", "", (ndll.haxelib != null && (ndll.haxelib.name == "hxcpp" || ndll.haxelib.name == "hxlibc")) ? ".dso" : ".ndll", applicationDirectory, project.debug, targetSuffix); + ProjectHelper.copyLibrary (project, ndll, "RPi", "", (ndll.haxelib != null && (ndll.haxelib.name == "hxcpp" || ndll.haxelib.name == "hxlibc")) ? ".dso" : ".ndll", applicationDirectory, project.debug, targetSuffix); } else { - FileHelper.copyLibrary (project, ndll, "Linux" + (is64 ? "64" : ""), "", (ndll.haxelib != null && (ndll.haxelib.name == "hxcpp" || ndll.haxelib.name == "hxlibc")) ? ".dso" : ".ndll", applicationDirectory, project.debug, targetSuffix); + ProjectHelper.copyLibrary (project, ndll, "Linux" + (is64 ? "64" : ""), "", (ndll.haxelib != null && (ndll.haxelib.name == "hxcpp" || ndll.haxelib.name == "hxlibc")) ? ".dso" : ".ndll", applicationDirectory, project.debug, targetSuffix); } @@ -237,7 +217,7 @@ class LinuxPlatform extends PlatformTarget { } - if (PlatformHelper.hostPlatform != Platform.WINDOWS && (targetType != "nodejs" && targetType != "java")) { + if (PlatformHelper.hostPlatform != WINDOWS && (targetType != "nodejs" && targetType != "java")) { ProcessHelper.runCommand ("", "chmod", [ "755", executablePath ]); @@ -324,7 +304,7 @@ class LinuxPlatform extends PlatformTarget { } - if (!targetFlags.exists ("64") && (command == "rebuild" || PlatformHelper.hostArchitecture == Architecture.X86)) { + if (!targetFlags.exists ("64") && (command == "rebuild" || PlatformHelper.hostArchitecture == X86)) { commands.push ([ "-Dlinux", "-DHXCPP_M32" ]); @@ -341,7 +321,7 @@ class LinuxPlatform extends PlatformTarget { var arguments = additionalArguments.copy (); - if (LogHelper.verbose) { + if (Log.verbose) { arguments.push ("-verbose"); @@ -359,7 +339,7 @@ class LinuxPlatform extends PlatformTarget { ProcessHelper.runCommand (applicationDirectory, "java", [ "-jar", project.app.file + ".jar" ].concat (arguments)); - } else if (project.target == PlatformHelper.hostPlatform) { + } else if (project.target == cast PlatformHelper.hostPlatform) { arguments = arguments.concat ([ "-livereload" ]); ProcessHelper.runCommand (applicationDirectory, "./" + Path.withoutDirectory (executablePath), arguments); @@ -382,7 +362,7 @@ class LinuxPlatform extends PlatformTarget { var path = PathHelper.combine (targetDirectory + "/obj/tmp", asset.targetPath); PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path); + AssetHelper.copyAsset (asset, path); asset.sourcePath = path; } @@ -429,12 +409,12 @@ class LinuxPlatform extends PlatformTarget { //SWFHelper.generateSWFClasses (project, targetDirectory + "/haxe"); - FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, targetType + "/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, targetType + "/hxml", targetDirectory + "/haxe", context); if (targetType == "cpp" && project.targetFlags.exists ("static")) { - FileHelper.recursiveSmartCopyTemplate (project, "cpp/static", targetDirectory + "/obj", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "cpp/static", targetDirectory + "/obj", context); } @@ -448,12 +428,12 @@ class LinuxPlatform extends PlatformTarget { if (asset.type != AssetType.TEMPLATE) { PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAssetIfNewer (asset, path); + AssetHelper.copyAssetIfNewer (asset, path); } else { PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path, context); + AssetHelper.copyAsset (asset, path, context); } @@ -466,9 +446,9 @@ class LinuxPlatform extends PlatformTarget { public override function watch ():Void { - var dirs = WatchHelper.processHXML (project, getDisplayHXML ()); - var command = WatchHelper.getCurrentCommand (); - WatchHelper.watch (project, command, dirs); + var dirs = WatchHelper.processHXML (getDisplayHXML (), project.app.path); + var command = ProjectHelper.getCurrentCommand (); + WatchHelper.watch (command, dirs); } diff --git a/tools/platforms/MacPlatform.hx b/tools/platforms/MacPlatform.hx index f373a60f6..d1017f6b9 100644 --- a/tools/platforms/MacPlatform.hx +++ b/tools/platforms/MacPlatform.hx @@ -3,55 +3,30 @@ package; import haxe.io.Path; import haxe.Template; -#if (hxp > "1.0.0") -import hxp.Architecture; -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.CPPHelper; -import hxp.CSHelper; -import hxp.DeploymentHelper; +import lime.tools.Architecture; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.CPPHelper; +import lime.tools.CSHelper; +import lime.tools.DeploymentHelper; import hxp.FileHelper; import hxp.GUID; import hxp.Haxelib; import hxp.HaxelibHelper; -import hxp.Icon; -import hxp.IconHelper; -import hxp.JavaHelper; -import hxp.LogHelper; -import hxp.NekoHelper; -import hxp.NodeJSHelper; +import lime.tools.Icon; +import lime.tools.IconHelper; +import lime.tools.JavaHelper; +import hxp.Log; +import lime.tools.NekoHelper; +import lime.tools.NodeJSHelper; import hxp.PathHelper; -import hxp.Platform; +import lime.tools.Platform; import hxp.PlatformHelper; -import hxp.PlatformTarget; +import lime.tools.PlatformTarget; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; +import lime.tools.ProjectHelper; import hxp.WatchHelper; -#else -import hxp.helpers.AssetHelper; -import hxp.helpers.CPPHelper; -import hxp.helpers.CSHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.GUID; -import hxp.helpers.FileHelper; -import hxp.helpers.HaxelibHelper; -import hxp.helpers.IconHelper; -import hxp.helpers.JavaHelper; -import hxp.helpers.LogHelper; -import hxp.helpers.NekoHelper; -import hxp.helpers.NodeJSHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.PlatformHelper; -import hxp.helpers.ProcessHelper; -import hxp.helpers.WatchHelper; -import hxp.project.AssetType; -import hxp.project.Architecture; -import hxp.project.Haxelib; -import hxp.project.HXProject in Project; -import hxp.project.Icon; -import hxp.project.Platform; -import hxp.project.PlatformTarget; -#end import sys.io.File; import sys.FileSystem; @@ -81,7 +56,7 @@ class MacPlatform extends PlatformTarget { } - if (project.targetFlags.exists ("neko") || project.target != PlatformHelper.hostPlatform) { + if (project.targetFlags.exists ("neko") || project.target != cast PlatformHelper.hostPlatform) { targetType = "neko"; @@ -129,7 +104,7 @@ class MacPlatform extends PlatformTarget { for (ndll in project.ndlls) { - FileHelper.copyLibrary (project, ndll, "Mac" + (is64 ? "64" : ""), "", (ndll.haxelib != null && (ndll.haxelib.name == "hxcpp" || ndll.haxelib.name == "hxlibc")) ? ".dylib" : ".ndll", executableDirectory, project.debug, targetSuffix); + ProjectHelper.copyLibrary (project, ndll, "Mac" + (is64 ? "64" : ""), "", (ndll.haxelib != null && (ndll.haxelib.name == "hxcpp" || ndll.haxelib.name == "hxlibc")) ? ".dylib" : ".ndll", executableDirectory, project.debug, targetSuffix); } @@ -226,7 +201,7 @@ class MacPlatform extends PlatformTarget { } - if (PlatformHelper.hostPlatform != Platform.WINDOWS && targetType != "nodejs" && targetType != "java") { + if (PlatformHelper.hostPlatform != WINDOWS && targetType != "nodejs" && targetType != "java") { ProcessHelper.runCommand ("", "chmod", [ "755", executablePath ]); @@ -291,13 +266,13 @@ class MacPlatform extends PlatformTarget { var commands = []; - if (!targetFlags.exists ("32") && (command == "rebuild" || PlatformHelper.hostArchitecture == Architecture.X64)) { + if (!targetFlags.exists ("32") && (command == "rebuild" || PlatformHelper.hostArchitecture == X64)) { commands.push ([ "-Dmac", "-DHXCPP_CLANG", "-DHXCPP_M64" ]); } - if (!targetFlags.exists ("64") && (command == "rebuild" || PlatformHelper.hostArchitecture == Architecture.X86)) { + if (!targetFlags.exists ("64") && (command == "rebuild" || PlatformHelper.hostArchitecture == X86)) { commands.push ([ "-Dmac", "-DHXCPP_CLANG", "-DHXCPP_M32" ]); @@ -312,7 +287,7 @@ class MacPlatform extends PlatformTarget { var arguments = additionalArguments.copy (); - if (LogHelper.verbose) { + if (Log.verbose) { arguments.push ("-verbose"); @@ -330,7 +305,7 @@ class MacPlatform extends PlatformTarget { ProcessHelper.runCommand (executableDirectory, "java", [ "-jar", project.app.file + ".jar" ].concat (arguments)); - } else if (project.target == PlatformHelper.hostPlatform) { + } else if (project.target == cast PlatformHelper.hostPlatform) { arguments = arguments.concat ([ "-livereload" ]); ProcessHelper.runCommand (executableDirectory, "./" + Path.withoutDirectory (executablePath), arguments); @@ -358,7 +333,7 @@ class MacPlatform extends PlatformTarget { var path = PathHelper.combine (targetDirectory + "/obj/tmp", asset.targetPath); PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path); + AssetHelper.copyAsset (asset, path); asset.sourcePath = path; } @@ -392,12 +367,12 @@ class MacPlatform extends PlatformTarget { //SWFHelper.generateSWFClasses (project, targetDirectory + "/haxe"); - FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, targetType + "/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, targetType + "/hxml", targetDirectory + "/haxe", context); if (targetType == "cpp" && project.targetFlags.exists ("static")) { - FileHelper.recursiveSmartCopyTemplate (project, "cpp/static", targetDirectory + "/obj", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "cpp/static", targetDirectory + "/obj", context); } @@ -421,12 +396,12 @@ class MacPlatform extends PlatformTarget { if (asset.type != AssetType.TEMPLATE) { PathHelper.mkdir (Path.directory (PathHelper.combine (contentDirectory, asset.targetPath))); - FileHelper.copyAssetIfNewer (asset, PathHelper.combine (contentDirectory, asset.targetPath)); + AssetHelper.copyAssetIfNewer (asset, PathHelper.combine (contentDirectory, asset.targetPath)); } else { PathHelper.mkdir (Path.directory (PathHelper.combine (targetDirectory, asset.targetPath))); - FileHelper.copyAsset (asset, PathHelper.combine (targetDirectory, asset.targetPath), context); + AssetHelper.copyAsset (asset, PathHelper.combine (targetDirectory, asset.targetPath), context); } @@ -439,9 +414,9 @@ class MacPlatform extends PlatformTarget { public override function watch ():Void { - var dirs = WatchHelper.processHXML (project, getDisplayHXML ()); - var command = WatchHelper.getCurrentCommand (); - WatchHelper.watch (project, command, dirs); + var dirs = WatchHelper.processHXML (getDisplayHXML (), project.app.path); + var command = ProjectHelper.getCurrentCommand (); + WatchHelper.watch (command, dirs); } diff --git a/tools/platforms/TVOSPlatform.hx b/tools/platforms/TVOSPlatform.hx index b43e990f0..52184674f 100644 --- a/tools/platforms/TVOSPlatform.hx +++ b/tools/platforms/TVOSPlatform.hx @@ -5,55 +5,30 @@ package; import haxe.io.Path; import haxe.Json; import haxe.Template; -#if (hxp > "1.0.0") -import hxp.Architecture; +import lime.tools.Architecture; import hxp.ArrayHelper; -import hxp.Asset; -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.CPPHelper; -import hxp.DeploymentHelper; +import lime.tools.Asset; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.CPPHelper; +import lime.tools.DeploymentHelper; import hxp.FileHelper; import hxp.Haxelib; -import hxp.Icon; -import hxp.IconHelper; -import hxp.Keystore; -import hxp.LogHelper; +import lime.tools.Icon; +import lime.tools.IconHelper; +import lime.tools.Keystore; +import hxp.Log; import hxp.NDLL; import hxp.PathHelper; -import hxp.Platform; +import lime.tools.Platform; import hxp.PlatformHelper; -import hxp.PlatformTarget; +import lime.tools.PlatformTarget; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; +import lime.tools.ProjectHelper; import hxp.StringHelper; -import hxp.TVOSHelper; +import lime.tools.TVOSHelper; import hxp.WatchHelper; -#else -import hxp.helpers.ArrayHelper; -import hxp.helpers.AssetHelper; -import hxp.helpers.CPPHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.FileHelper; -import hxp.helpers.IconHelper; -import hxp.helpers.LogHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.PlatformHelper; -import hxp.helpers.ProcessHelper; -import hxp.helpers.StringHelper; -import hxp.helpers.TVOSHelper; -import hxp.helpers.WatchHelper; -import hxp.project.Architecture; -import hxp.project.Asset; -import hxp.project.AssetType; -import hxp.project.Haxelib; -import hxp.project.HXProject in Project; -import hxp.project.Icon; -import hxp.project.Keystore; -import hxp.project.NDLL; -import hxp.project.Platform; -import hxp.project.PlatformTarget; -#end #if lime import lime.graphics.Image; #end @@ -75,7 +50,7 @@ class TVOSPlatform extends PlatformTarget { public override function build ():Void { - if (project.targetFlags.exists ("xcode") && PlatformHelper.hostPlatform == Platform.MAC) { + if (project.targetFlags.exists ("xcode") && PlatformHelper.hostPlatform == MAC) { ProcessHelper.runCommand ("", "open", [ targetDirectory + "/" + project.app.file + ".xcodeproj" ] ); @@ -395,7 +370,7 @@ class TVOSPlatform extends PlatformTarget { var path = PathHelper.combine (targetDirectory + "/" + project.app.file + "/obj/tmp", asset.targetPath); PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path); + AssetHelper.copyAsset (asset, path); asset.sourcePath = path; } @@ -497,7 +472,7 @@ class TVOSPlatform extends PlatformTarget { if (!FileSystem.exists (imagePath)) { #if (lime && lime_cffi && !macro) - LogHelper.info ("", " - \x1b[1mGenerating image:\x1b[0m " + imagePath); + Log.info ("", " - \x1b[1mGenerating image:\x1b[0m " + imagePath); var image = new Image (null, 0, 0, size.w, size.h, (0xFF << 24) | (project.window.background & 0xFFFFFF)); var bytes = image.encode (PNG); @@ -516,15 +491,15 @@ class TVOSPlatform extends PlatformTarget { PathHelper.mkdir (projectDirectory + "/resources"); PathHelper.mkdir (projectDirectory + "/haxe/build"); - FileHelper.recursiveSmartCopyTemplate (project, "tvos/resources", projectDirectory + "/resources", context, true, false); - FileHelper.recursiveSmartCopyTemplate (project, "tvos/PROJ/haxe", projectDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "haxe", projectDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "tvos/PROJ/Classes", projectDirectory + "/Classes", context); - FileHelper.recursiveSmartCopyTemplate (project, "tvos/PROJ/Images.xcassets", projectDirectory + "/Images.xcassets", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "tvos/resources", projectDirectory + "/resources", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "tvos/PROJ/haxe", projectDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", projectDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "tvos/PROJ/Classes", projectDirectory + "/Classes", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "tvos/PROJ/Images.xcassets", projectDirectory + "/Images.xcassets", context); FileHelper.copyFileTemplate (project.templatePaths, "tvos/PROJ/PROJ-Entitlements.plist", projectDirectory + "/" + project.app.file + "-Entitlements.plist", context); FileHelper.copyFileTemplate (project.templatePaths, "tvos/PROJ/PROJ-Info.plist", projectDirectory + "/" + project.app.file + "-Info.plist", context); FileHelper.copyFileTemplate (project.templatePaths, "tvos/PROJ/PROJ-Prefix.pch", projectDirectory + "/" + project.app.file + "-Prefix.pch", context); - FileHelper.recursiveSmartCopyTemplate (project, "tvos/PROJ.xcodeproj", targetDirectory + "/" + project.app.file + ".xcodeproj", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "tvos/PROJ.xcodeproj", targetDirectory + "/" + project.app.file + ".xcodeproj", context); //SWFHelper.generateSWFClasses (project, projectDirectory + "/haxe"); @@ -547,16 +522,16 @@ class TVOSPlatform extends PlatformTarget { //if (ndll.haxelib != null) { var releaseLib = PathHelper.getLibraryPath (ndll, "AppleTV", "lib", libExt); - LogHelper.info("releaseLib: " + releaseLib); + Log.info("releaseLib: " + releaseLib); var debugLib = PathHelper.getLibraryPath (ndll, "AppleTV", "lib", libExt, true); var releaseDest = projectDirectory + "/lib/" + arch + "/lib" + ndll.name + ".a"; - LogHelper.info("releaseDest: " + releaseDest); + Log.info("releaseDest: " + releaseDest); var debugDest = projectDirectory + "/lib/" + arch + "-debug/lib" + ndll.name + ".a"; if (!FileSystem.exists (releaseLib)) { releaseLib = PathHelper.getLibraryPath (ndll, "AppleTV", "lib", ".appletvos-64.a"); - LogHelper.info("alternative releaseLib: " + releaseLib); + Log.info("alternative releaseLib: " + releaseLib); debugLib = PathHelper.getLibraryPath (ndll, "AppleTV", "lib", ".appletvos-64.a", true); } @@ -608,7 +583,7 @@ class TVOSPlatform extends PlatformTarget { //var sourceAssetPath:String = projectDirectory + "haxe/" + asset.sourcePath; PathHelper.mkdir (Path.directory (targetPath)); - FileHelper.copyAssetIfNewer (asset, targetPath); + AssetHelper.copyAssetIfNewer (asset, targetPath); //PathHelper.mkdir (Path.directory (sourceAssetPath)); //FileHelper.linkFile (flatAssetPath, sourceAssetPath, true, true); @@ -618,13 +593,13 @@ class TVOSPlatform extends PlatformTarget { var targetPath = PathHelper.combine (projectDirectory, asset.targetPath); PathHelper.mkdir (Path.directory (targetPath)); - FileHelper.copyAsset (asset, targetPath, context); + AssetHelper.copyAsset (asset, targetPath, context); } } - if (project.targetFlags.exists ("xcode") && PlatformHelper.hostPlatform == Platform.MAC && command == "update") { + if (project.targetFlags.exists ("xcode") && PlatformHelper.hostPlatform == MAC && command == "update") { ProcessHelper.runCommand ("", "open", [ targetDirectory + "/" + project.app.file + ".xcodeproj" ] ); @@ -656,9 +631,9 @@ class TVOSPlatform extends PlatformTarget { public override function watch ():Void { - var dirs = WatchHelper.processHXML (project, getDisplayHXML ()); - var command = WatchHelper.getCurrentCommand (); - WatchHelper.watch (project, command, dirs); + var dirs = WatchHelper.processHXML (getDisplayHXML (), project.app.path); + var command = ProjectHelper.getCurrentCommand (); + WatchHelper.watch (command, dirs); } diff --git a/tools/platforms/TizenPlatform.hx b/tools/platforms/TizenPlatform.hx index 05af9d969..1d9c208ed 100644 --- a/tools/platforms/TizenPlatform.hx +++ b/tools/platforms/TizenPlatform.hx @@ -3,33 +3,19 @@ package; import haxe.io.Path; import haxe.Template; -#if (hxp > "1.0.0") -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.CPPHelper; -import hxp.DeploymentHelper; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.CPPHelper; +import lime.tools.DeploymentHelper; import hxp.FileHelper; -import hxp.Icon; -import hxp.IconHelper; +import lime.tools.Icon; +import lime.tools.IconHelper; import hxp.PathHelper; -import hxp.PlatformTarget; +import lime.tools.PlatformTarget; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; +import lime.tools.ProjectHelper; import hxp.TizenHelper; -#else -import hxp.helpers.AssetHelper; -import hxp.helpers.CPPHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.FileHelper; -import hxp.helpers.IconHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.ProcessHelper; -import hxp.helpers.TizenHelper; -import hxp.project.AssetType; -import hxp.project.HXProject in Project; -import hxp.project.Icon; -import hxp.project.PlatformTarget; -#end import sys.io.File; import sys.FileSystem; @@ -63,7 +49,7 @@ class TizenPlatform extends PlatformTarget { for (ndll in project.ndlls) { - FileHelper.copyLibrary (project, ndll, "Tizen", "", arch + ".so", destination + "lib/", project.debug, ".so"); + ProjectHelper.copyLibrary (project, ndll, "Tizen", "", arch + ".so", destination + "lib/", project.debug, ".so"); } @@ -164,7 +150,7 @@ class TizenPlatform extends PlatformTarget { var path = PathHelper.combine (targetDirectory + "/obj/tmp", asset.targetPath); PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path); + AssetHelper.copyAsset (asset, path); asset.sourcePath = path; } @@ -208,9 +194,9 @@ class TizenPlatform extends PlatformTarget { } - FileHelper.recursiveSmartCopyTemplate (project, "tizen/template", destination, context); - FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "tizen/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "tizen/template", destination, context); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "tizen/hxml", targetDirectory + "/haxe", context); for (asset in project.assets) { @@ -222,19 +208,19 @@ class TizenPlatform extends PlatformTarget { if (asset.targetPath == "/appinfo.json") { - FileHelper.copyAsset (asset, path, context); + AssetHelper.copyAsset (asset, path, context); } else { // going to root directory now, but should it be a forced "assets" folder later? - FileHelper.copyAssetIfNewer (asset, path); + AssetHelper.copyAssetIfNewer (asset, path); } } else { - FileHelper.copyAsset (asset, path, context); + AssetHelper.copyAsset (asset, path, context); } diff --git a/tools/platforms/WindowsPlatform.hx b/tools/platforms/WindowsPlatform.hx index d178d4ee9..0b8a83a98 100644 --- a/tools/platforms/WindowsPlatform.hx +++ b/tools/platforms/WindowsPlatform.hx @@ -3,59 +3,32 @@ package; import haxe.io.Path; import haxe.Template; -#if (hxp > "1.0.0") -import hxp.Architecture; -import hxp.Asset; -import hxp.AssetHelper; -import hxp.AssetType; -import hxp.CPPHelper; -import hxp.CSHelper; -import hxp.DeploymentHelper; +import lime.tools.Architecture; +import lime.tools.Asset; +import lime.tools.AssetHelper; +import lime.tools.AssetType; +import lime.tools.CPPHelper; +import lime.tools.CSHelper; +import lime.tools.DeploymentHelper; import hxp.FileHelper; import hxp.GUID; import hxp.Haxelib; -import hxp.HTML5Helper; -import hxp.Icon; -import hxp.IconHelper; -import hxp.JavaHelper; -import hxp.LogHelper; -import hxp.ModuleHelper; -import hxp.NekoHelper; -import hxp.NodeJSHelper; +import lime.tools.HTML5Helper; +import lime.tools.Icon; +import lime.tools.IconHelper; +import lime.tools.JavaHelper; +import hxp.Log; +import lime.tools.ModuleHelper; +import lime.tools.NekoHelper; +import lime.tools.NodeJSHelper; import hxp.PathHelper; -import hxp.Platform; +import lime.tools.Platform; import hxp.PlatformHelper; -import hxp.PlatformTarget; +import lime.tools.PlatformTarget; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; +import lime.tools.ProjectHelper; import hxp.WatchHelper; -#else -import hxp.project.Icon; -import hxp.helpers.AssetHelper; -import hxp.helpers.CPPHelper; -import hxp.helpers.DeploymentHelper; -import hxp.helpers.FileHelper; -import hxp.helpers.HTML5Helper; -import hxp.helpers.IconHelper; -import hxp.helpers.JavaHelper; -import hxp.helpers.LogHelper; -import hxp.helpers.ModuleHelper; -import hxp.helpers.CSHelper; -import hxp.helpers.GUID; -import hxp.helpers.NekoHelper; -import hxp.helpers.NodeJSHelper; -import hxp.helpers.PathHelper; -import hxp.helpers.PlatformHelper; -import hxp.helpers.ProcessHelper; -import hxp.helpers.WatchHelper; -import hxp.project.Architecture; -import hxp.project.Asset; -import hxp.project.AssetType; -import hxp.project.Haxelib; -import hxp.project.HXProject in Project; -import hxp.project.Platform; -import hxp.project.PlatformTarget; -#end import sys.io.File; import sys.FileSystem; @@ -78,7 +51,7 @@ class WindowsPlatform extends PlatformTarget { targetType = "winjs"; - } else if (project.targetFlags.exists ("neko") || project.target != PlatformHelper.hostPlatform) { + } else if (project.targetFlags.exists ("neko") || project.target != cast PlatformHelper.hostPlatform) { targetType = "neko"; @@ -198,7 +171,7 @@ class WindowsPlatform extends PlatformTarget { for (ndll in project.ndlls) { - FileHelper.copyLibrary (project, ndll, "Windows" + (is64 ? "64" : ""), "", (ndll.haxelib != null && (ndll.haxelib.name == "hxcpp" || ndll.haxelib.name == "hxlibc")) ? ".dll" : ".ndll", applicationDirectory, project.debug, targetSuffix); + ProjectHelper.copyLibrary (project, ndll, "Windows" + (is64 ? "64" : ""), "", (ndll.haxelib != null && (ndll.haxelib.name == "hxcpp" || ndll.haxelib.name == "hxlibc")) ? ".dll" : ".ndll", applicationDirectory, project.debug, targetSuffix); } @@ -325,7 +298,7 @@ class WindowsPlatform extends PlatformTarget { var iconPath = PathHelper.combine (applicationDirectory, "icon.ico"); - if (IconHelper.createWindowsIcon (icons, iconPath) && PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (IconHelper.createWindowsIcon (icons, iconPath) && PlatformHelper.hostPlatform == WINDOWS) { var templates = [ PathHelper.getHaxelib (new Haxelib (#if lime "lime" #else "hxp" #end)) + "/templates" ].concat (project.templatePaths); ProcessHelper.runCommand ("", PathHelper.findTemplate (templates, "bin/ReplaceVistaIcon.exe"), [ executablePath, iconPath, "1" ], true, true); @@ -446,7 +419,7 @@ class WindowsPlatform extends PlatformTarget { } - if (!targetFlags.exists ("64") && (command == "rebuild" || PlatformHelper.hostArchitecture == Architecture.X86)) { + if (!targetFlags.exists ("64") && (command == "rebuild" || PlatformHelper.hostArchitecture == X86)) { if (targetFlags.exists ("winrt")) { @@ -471,7 +444,7 @@ class WindowsPlatform extends PlatformTarget { var arguments = additionalArguments.copy (); - if (LogHelper.verbose) { + if (Log.verbose) { arguments.push ("-verbose"); @@ -554,7 +527,7 @@ class WindowsPlatform extends PlatformTarget { ProcessHelper.runCommand (applicationDirectory, "java", [ "-jar", project.app.file + ".jar" ].concat (arguments)); - } else if (project.target == PlatformHelper.hostPlatform) { + } else if (project.target == cast PlatformHelper.hostPlatform) { arguments = arguments.concat ([ "-livereload" ]); ProcessHelper.runCommand (applicationDirectory, Path.withoutDirectory (executablePath), arguments); @@ -589,7 +562,7 @@ class WindowsPlatform extends PlatformTarget { var path = PathHelper.combine (targetDirectory + "/obj/tmp", asset.targetPath); PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path); + AssetHelper.copyAsset (asset, path); asset.sourcePath = path; } @@ -637,12 +610,12 @@ class WindowsPlatform extends PlatformTarget { //SWFHelper.generateSWFClasses (project, targetDirectory + "/haxe"); - FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, targetType + "/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, targetType + "/hxml", targetDirectory + "/haxe", context); if (targetType == "cpp" && project.targetFlags.exists ("static")) { - FileHelper.recursiveSmartCopyTemplate (project, "cpp/static", targetDirectory + "/obj", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "cpp/static", targetDirectory + "/obj", context); } @@ -662,12 +635,12 @@ class WindowsPlatform extends PlatformTarget { if (asset.type != AssetType.TEMPLATE) { PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAssetIfNewer (asset, path); + AssetHelper.copyAssetIfNewer (asset, path); } else { PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path, context); + AssetHelper.copyAsset (asset, path, context); } @@ -738,7 +711,7 @@ class WindowsPlatform extends PlatformTarget { } - if (LogHelper.verbose) { + if (Log.verbose) { project.haxedefs.set ("verbose", 1); @@ -819,7 +792,7 @@ class WindowsPlatform extends PlatformTarget { if (asset.type != AssetType.FONT) { PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAssetIfNewer (asset, path); + AssetHelper.copyAssetIfNewer (asset, path); } else if (useWebfonts) { @@ -835,7 +808,7 @@ class WindowsPlatform extends PlatformTarget { } else { - LogHelper.warn ("Could not find generated font file \"" + source + extension + "\""); + Log.warn ("Could not find generated font file \"" + source + extension + "\""); } @@ -847,7 +820,7 @@ class WindowsPlatform extends PlatformTarget { } - FileHelper.recursiveSmartCopyTemplate (project, "winjs/template", targetDirectory, context); + ProjectHelper.recursiveSmartCopyTemplate (project, "winjs/template", targetDirectory, context); var renamePaths = [ "uwp-project.sln", "source/uwp-project.jsproj", "source/uwp-project_TemporaryKey.pfx" ]; var fullPath; @@ -871,13 +844,13 @@ class WindowsPlatform extends PlatformTarget { if (project.app.main != null) { - FileHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); - FileHelper.recursiveSmartCopyTemplate (project, "winjs/haxe", targetDirectory + "/haxe", context, true, false); - FileHelper.recursiveSmartCopyTemplate (project, "winjs/hxml", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "haxe", targetDirectory + "/haxe", context); + ProjectHelper.recursiveSmartCopyTemplate (project, "winjs/haxe", targetDirectory + "/haxe", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "winjs/hxml", targetDirectory + "/haxe", context); if (project.targetFlags.exists ("webgl")) { - FileHelper.recursiveSmartCopyTemplate (project, "webgl/hxml", targetDirectory + "/haxe", context, true, false); + ProjectHelper.recursiveSmartCopyTemplate (project, "webgl/hxml", targetDirectory + "/haxe", context, true, false); } @@ -890,7 +863,7 @@ class WindowsPlatform extends PlatformTarget { if (asset.type == AssetType.TEMPLATE) { PathHelper.mkdir (Path.directory (path)); - FileHelper.copyAsset (asset, path, context); + AssetHelper.copyAsset (asset, path, context); } @@ -901,9 +874,9 @@ class WindowsPlatform extends PlatformTarget { public override function watch ():Void { - var dirs = WatchHelper.processHXML (project, getDisplayHXML ()); - var command = WatchHelper.getCurrentCommand (); - WatchHelper.watch (project, command, dirs); + var dirs = WatchHelper.processHXML (getDisplayHXML (), project.app.path); + var command = ProjectHelper.getCurrentCommand (); + WatchHelper.watch (command, dirs); } diff --git a/tools/utils/CreateTemplate.hx b/tools/utils/CreateTemplate.hx index 459aa2001..5fcd58198 100644 --- a/tools/utils/CreateTemplate.hx +++ b/tools/utils/CreateTemplate.hx @@ -1,25 +1,17 @@ package utils; -#if (hxp > "1.0.0") import hxp.FileHelper; import hxp.Haxelib; import hxp.HaxelibHelper; -import hxp.LogHelper; +import hxp.Log; import hxp.PathHelper; -import hxp.Project; -#else -import hxp.helpers.FileHelper; -import hxp.helpers.HaxelibHelper; -import hxp.helpers.LogHelper; -import hxp.helpers.PathHelper; -import hxp.project.Haxelib; -import hxp.project.HXProject in Project; -#end +import lime.tools.Project; +import lime.tools.ProjectHelper; import sys.FileSystem; -@:access(hxp.Project) -@:access(hxp.project.HXProject) +@:access(lime.tools.Project) +@:access(lime.tools.Project.HXProject) class CreateTemplate { @@ -295,7 +287,7 @@ class CreateTemplate { }*/ PathHelper.mkdir (folder); - FileHelper.recursiveSmartCopyTemplate (project, "project", folder, context); + ProjectHelper.recursiveSmartCopyTemplate (project, "project", folder, context); try { @@ -319,7 +311,7 @@ class CreateTemplate { } - LogHelper.error ("Could not find project \"" + projectName + "\""); + Log.error ("Could not find project \"" + projectName + "\""); } @@ -364,7 +356,7 @@ class CreateTemplate { if (sampleName == null || sampleName == "") { - LogHelper.error ("You must specify a sample name to copy when using \"" + CommandLineTools.commandName + " create\""); + Log.error ("You must specify a sample name to copy when using \"" + CommandLineTools.commandName + " create\""); return; } @@ -409,7 +401,7 @@ class CreateTemplate { } - LogHelper.error ("Could not find sample \"" + sampleName + "\" in project \"" + projectName + "\""); + Log.error ("Could not find sample \"" + sampleName + "\" in project \"" + projectName + "\""); } @@ -471,25 +463,25 @@ class CreateTemplate { } - LogHelper.println ("\x1b[1mYou must specify a template when using the 'create' command.\x1b[0m"); - LogHelper.println (""); + Log.println ("\x1b[1mYou must specify a template when using the 'create' command.\x1b[0m"); + Log.println (""); if (projectName == CommandLineTools.commandName) { - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + CommandLineTools.commandName + "\x1b[0m create project (directory)"); - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + CommandLineTools.commandName + "\x1b[0m create extension (directory)"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + CommandLineTools.commandName + "\x1b[0m create project (directory)"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + CommandLineTools.commandName + "\x1b[0m create extension (directory)"); } - LogHelper.println (" " + LogHelper.accentColor + "Usage:\x1b[0m \x1b[1m" + CommandLineTools.commandName + "\x1b[0m create " + (projectName != CommandLineTools.commandName ? projectName + " " : "") + " (directory)"); + Log.println (" " + Log.accentColor + "Usage:\x1b[0m \x1b[1m" + CommandLineTools.commandName + "\x1b[0m create " + (projectName != CommandLineTools.commandName ? projectName + " " : "") + " (directory)"); if (templates.length > 0) { - LogHelper.println (""); - LogHelper.println (" " + LogHelper.accentColor + "Available samples:\x1b[0m"); - LogHelper.println (""); + Log.println (""); + Log.println (" " + Log.accentColor + "Available samples:\x1b[0m"); + Log.println (""); for (template in templates) { diff --git a/tools/utils/JavaExternGenerator.hx b/tools/utils/JavaExternGenerator.hx index 794133c8a..7453fa088 100644 --- a/tools/utils/JavaExternGenerator.hx +++ b/tools/utils/JavaExternGenerator.hx @@ -10,11 +10,11 @@ import haxe.zip.Reader; #if (hxp > "1.0.0") import hxp.PathHelper; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; #else import hxp.helpers.PathHelper; import hxp.helpers.ProcessHelper; -import hxp.project.HXProject in Project; +import lime.tools.Project.HXProject in Project; #end import sys.io.File; import sys.io.Process; diff --git a/tools/utils/PlatformSetup.hx b/tools/utils/PlatformSetup.hx index 8ac9d45e5..fa3650d86 100644 --- a/tools/utils/PlatformSetup.hx +++ b/tools/utils/PlatformSetup.hx @@ -6,31 +6,31 @@ import haxe.io.Eof; import haxe.io.Path; import haxe.zip.Reader; #if (hxp > "1.0.0") -import hxp.CLIHelper; -import hxp.ConfigHelper; +import lime.tools.CLIHelper; +import lime.tools.ConfigHelper; import hxp.FileHelper; import hxp.Haxelib; import hxp.HaxelibHelper; -import hxp.LogHelper; +import hxp.Log; import hxp.PathHelper; -import hxp.Platform; +import lime.tools.Platform; import hxp.PlatformHelper; import hxp.ProcessHelper; -import hxp.Project; +import lime.tools.Project; import hxp.Version; #else import hxp.helpers.CLIHelper; import hxp.helpers.ConfigHelper; import hxp.helpers.FileHelper; import hxp.helpers.HaxelibHelper; -import hxp.helpers.LogHelper; +import hxp.helpers.Log; import hxp.helpers.PathHelper; import hxp.helpers.PlatformHelper; import hxp.helpers.ProcessHelper; -import hxp.project.Haxelib; -import hxp.project.HXProject in Project; -import hxp.project.Platform; -import hxp.project.Version; +import lime.tools.Project.Haxelib; +import lime.tools.Project.HXProject in Project; +import lime.tools.Project.Platform; +import lime.tools.Project.Version; #end import sys.io.File; import sys.io.Process; @@ -117,7 +117,7 @@ class PlatformSetup { if (!followingLocation) { - LogHelper.println ("Downloading " + localPath + "..."); + Log.println ("Downloading " + localPath + "..."); } @@ -217,13 +217,13 @@ class PlatformSetup { if (file == "") { - if (path != "") LogHelper.println (" Created " + path); + if (path != "") Log.println (" Created " + path); continue; // was just a directory } path += file; - LogHelper.println (" Install " + path); + Log.println (" Install " + path); var data = Reader.unzip (entry); var f = File.write (targetPath + "/" + path, true); @@ -238,7 +238,7 @@ class PlatformSetup { } - LogHelper.println ("Done"); + Log.println ("Done"); } @@ -253,7 +253,7 @@ class PlatformSetup { } - var inputValue = unescapePath (CLIHelper.param (LogHelper.accentColor + description + "\x1b[0m \x1b[37;3m[" + (value != null ? value : "") + "]\x1b[0m")); + var inputValue = unescapePath (CLIHelper.param (Log.accentColor + description + "\x1b[0m \x1b[37;3m[" + (value != null ? value : "") + "]\x1b[0m")); if (inputValue != "" && inputValue != value) { @@ -310,7 +310,7 @@ class PlatformSetup { // } else { - // LogHelper.println ("Warning : No 'HOME' variable set - ~/.lime/config.xml might be missing."); + // Log.println ("Warning : No 'HOME' variable set - ~/.lime/config.xml might be missing."); // return null; @@ -409,7 +409,7 @@ class PlatformSetup { } else { - LogHelper.error ("Could not find version \"" + haxelib.version + "\" for haxelib \"" + haxelib.name + "\""); + Log.error ("Could not find version \"" + haxelib.version + "\" for haxelib \"" + haxelib.name + "\""); } @@ -438,11 +438,11 @@ class PlatformSetup { private static function openURL (url:String):Void { - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { Sys.command ("explorer", [ url ]); - } else if (PlatformHelper.hostPlatform == Platform.LINUX) { + } else if (PlatformHelper.hostPlatform == LINUX) { ProcessHelper.runCommand ("", "xdg-open", [ url ], false); @@ -495,12 +495,12 @@ class PlatformSetup { case "html5": - LogHelper.println ("\x1b[0;3mNo additional configuration is required.\x1b[0m"); + Log.println ("\x1b[0;3mNo additional configuration is required.\x1b[0m"); //setupHTML5 (); case "ios", "iphoneos", "iphonesim": - if (PlatformHelper.hostPlatform == Platform.MAC) { + if (PlatformHelper.hostPlatform == MAC) { setupIOS (); @@ -508,7 +508,7 @@ class PlatformSetup { case "linux": - if (PlatformHelper.hostPlatform == Platform.LINUX) { + if (PlatformHelper.hostPlatform == LINUX) { setupLinux (); @@ -516,7 +516,7 @@ class PlatformSetup { case "mac", "macos": - if (PlatformHelper.hostPlatform == Platform.MAC) { + if (PlatformHelper.hostPlatform == MAC) { setupMac (); @@ -536,7 +536,7 @@ class PlatformSetup { case "windows", "winrt": - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { setupWindows (); @@ -544,7 +544,7 @@ class PlatformSetup { case "neko", "hl", "cs", "uwp", "winjs", "nodejs", "java": - LogHelper.println ("\x1b[0;3mNo additional configuration is required.\x1b[0m"); + Log.println ("\x1b[0;3mNo additional configuration is required.\x1b[0m"); case "lime": @@ -556,7 +556,7 @@ class PlatformSetup { case "tvos", "tvsim": - if (PlatformHelper.hostPlatform == Platform.MAC) { + if (PlatformHelper.hostPlatform == MAC) { setupIOS (); @@ -589,17 +589,17 @@ class PlatformSetup { private static function runInstaller (path:String, message:String = "Waiting for process to complete..."):Void { - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { try { - LogHelper.println (message); + Log.println (message); ProcessHelper.runCommand ("", "call", [ path ], false); - LogHelper.println ("Done"); + Log.println ("Done"); } catch (e:Dynamic) {} - } else if (PlatformHelper.hostPlatform == Platform.LINUX) { + } else if (PlatformHelper.hostPlatform == LINUX) { if (Path.extension (path) == "deb") { @@ -607,7 +607,7 @@ class PlatformSetup { } else { - LogHelper.println (message); + Log.println (message); Sys.command ("chmod", [ "755", path ]); if (path.substr (0, 1) == "/") { @@ -620,7 +620,7 @@ class PlatformSetup { } - LogHelper.println ("Done"); + Log.println ("Done"); } @@ -628,10 +628,10 @@ class PlatformSetup { if (Path.extension (path) == "") { - LogHelper.println (message); + Log.println (message); Sys.command ("chmod", [ "755", path ]); ProcessHelper.runCommand ("", path, [], false); - LogHelper.println ("Done"); + Log.println ("Done"); } else if (Path.extension (path) == "dmg") { @@ -694,9 +694,9 @@ class PlatformSetup { if (file != "") { - LogHelper.println (message); + Log.println (message); ProcessHelper.runCommand ("", "open", [ "-W", volumePath + "/" + file ], false); - LogHelper.println ("Done"); + Log.println ("Done"); } @@ -735,31 +735,31 @@ class PlatformSetup { public static function setupAIR ():Void { - LogHelper.println ("\x1b[1mIn order to package SWF applications using Adobe AIR, you must"); - LogHelper.println ("download and extract the Adobe AIR SDK."); - LogHelper.println (""); + Log.println ("\x1b[1mIn order to package SWF applications using Adobe AIR, you must"); + Log.println ("download and extract the Adobe AIR SDK."); + Log.println (""); getDefineValue ("AIR_SDK", "Path to AIR SDK"); - LogHelper.println (""); - LogHelper.println ("Setup complete."); + Log.println (""); + Log.println ("Setup complete."); } public static function setupAndroid ():Void { - LogHelper.println ("\x1b[1mIn order to build applications for Android, you must have recent"); - LogHelper.println ("versions of the Android SDK, Android NDK and Java JDK installed."); - LogHelper.println (""); - LogHelper.println ("You must also install the Android SDK Platform-tools and API 19 using"); - LogHelper.println ("the SDK manager from Android Studio.\x1b[0m"); - LogHelper.println (""); + Log.println ("\x1b[1mIn order to build applications for Android, you must have recent"); + Log.println ("versions of the Android SDK, Android NDK and Java JDK installed."); + Log.println (""); + Log.println ("You must also install the Android SDK Platform-tools and API 19 using"); + Log.println ("the SDK manager from Android Studio.\x1b[0m"); + Log.println (""); getDefineValue ("ANDROID_SDK", "Path to Android SDK"); getDefineValue ("ANDROID_NDK_ROOT", "Path to Android NDK"); - if (PlatformHelper.hostPlatform != Platform.MAC) { + if (PlatformHelper.hostPlatform != MAC) { getDefineValue ("JAVA_HOME", "Path to Java JDK"); @@ -771,39 +771,39 @@ class PlatformSetup { } - LogHelper.println (""); - LogHelper.println ("Setup complete."); + Log.println (""); + Log.println ("Setup complete."); } public static function setupElectron ():Void { - LogHelper.println ("\x1b[1mIn order to run Electron applications, you must download"); - LogHelper.println ("and extract the Electron runtime on your system."); - LogHelper.println (""); + Log.println ("\x1b[1mIn order to run Electron applications, you must download"); + Log.println ("and extract the Electron runtime on your system."); + Log.println (""); getDefineValue ("ELECTRON_PATH", "Path to Electron runtime"); - LogHelper.println (""); + Log.println (""); HaxelibHelper.runCommand ("", [ "install", "electron" ], true, true); - LogHelper.println (""); - LogHelper.println ("Setup complete."); + Log.println (""); + Log.println ("Setup complete."); } public static function setupEmscripten ():Void { - LogHelper.println ("\x1b[1mIn order to build for WebAssembly or asm.js, you must download"); - LogHelper.println ("and install the Emscripten SDK."); - LogHelper.println (""); + Log.println ("\x1b[1mIn order to build for WebAssembly or asm.js, you must download"); + Log.println ("and install the Emscripten SDK."); + Log.println (""); getDefineValue ("EMSCRIPTEN_SDK", "Path to Emscripten SDK"); - LogHelper.println (""); - LogHelper.println ("Setup complete."); + Log.println (""); + Log.println ("Setup complete."); } @@ -842,7 +842,7 @@ class PlatformSetup { if (defines.exists ("dev")) { - LogHelper.error ("Could not find dependency \"" + lib.name + "\" for library \"" + haxelib.name + "\""); + Log.error ("Could not find dependency \"" + lib.name + "\" for library \"" + haxelib.name + "\""); } @@ -860,7 +860,7 @@ class PlatformSetup { } else if (!dependency) { - //LogHelper.warn ("No setup is required for " + haxelib.name + ", or it is not a valid target"); + //Log.warn ("No setup is required for " + haxelib.name + ", or it is not a valid target"); } @@ -879,7 +879,7 @@ class PlatformSetup { // var downloadPath = ""; // var defaultInstallPath = ""; - // if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + // if (PlatformHelper.hostPlatform == WINDOWS) { // defaultInstallPath = "C:\\Development\\Apache Cordova"; @@ -939,7 +939,7 @@ class PlatformSetup { // } - // if (PlatformHelper.hostPlatform != Platform.WINDOWS) { + // if (PlatformHelper.hostPlatform != WINDOWS) { // ProcessHelper.runCommand ("", "chmod", [ "-R", "777", path ], false); @@ -948,7 +948,7 @@ class PlatformSetup { // setApacheCordova = true; // defines.set ("CORDOVA_PATH", path); // writeConfig (defines.get ("LIME_CONFIG"), defines); - // LogHelper.println (""); + // Log.println (""); // } @@ -987,11 +987,11 @@ class PlatformSetup { public static function setupIOS ():Void { - LogHelper.println ("\x1b[1mIn order to build applications for iOS and tvOS, you must have"); - LogHelper.println ("Xcode installed. Xcode is available from Apple as a free download.\x1b[0m"); - LogHelper.println (""); - LogHelper.println ("\x1b[0;3mNo additional configuration is required.\x1b[0m"); - LogHelper.println (""); + Log.println ("\x1b[1mIn order to build applications for iOS and tvOS, you must have"); + Log.println ("Xcode installed. Xcode is available from Apple as a free download.\x1b[0m"); + Log.println (""); + Log.println ("\x1b[0;3mNo additional configuration is required.\x1b[0m"); + Log.println (""); var answer = CLIHelper.ask ("Would you like to visit the download page now?"); @@ -1014,7 +1014,7 @@ class PlatformSetup { var haxePath = Sys.getEnv ("HAXEPATH"); - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { if (haxePath == null || haxePath == "") { @@ -1074,7 +1074,7 @@ class PlatformSetup { } - if (PlatformHelper.hostPlatform == Platform.MAC) { + if (PlatformHelper.hostPlatform == MAC) { ConfigHelper.writeConfigValue ("MAC_USE_CURRENT_SDK", "1"); @@ -1101,8 +1101,8 @@ class PlatformSetup { var parameters = [ "apt-get", "install" ].concat (packages.split (" ")); ProcessHelper.runCommand ("", "sudo", parameters, false); - LogHelper.println (""); - LogHelper.println ("Setup complete."); + Log.println (""); + Log.println ("Setup complete."); return; } @@ -1115,8 +1115,8 @@ class PlatformSetup { var parameters = [ "yum", "install" ].concat (linuxYumPackages.split (" ")); ProcessHelper.runCommand ("", "sudo", parameters, false); - LogHelper.println (""); - LogHelper.println ("Setup complete."); + Log.println (""); + Log.println ("Setup complete."); return; } @@ -1129,8 +1129,8 @@ class PlatformSetup { var parameters = [ "dnf", "install" ].concat (linuxDnfPackages.split (" ")); ProcessHelper.runCommand ("", "sudo", parameters, false); - LogHelper.println (""); - LogHelper.println ("Setup complete."); + Log.println (""); + Log.println ("Setup complete."); return; } @@ -1144,8 +1144,8 @@ class PlatformSetup { var parameters = [ "-l", "-c", "equo", "i", "-av" ].concat (linuxEquoPackages.split (" ")); ProcessHelper.runCommand ("", "su", parameters, false); - LogHelper.println (""); - LogHelper.println ("Setup complete."); + Log.println (""); + Log.println ("Setup complete."); return; } @@ -1158,8 +1158,8 @@ class PlatformSetup { var parameters = [ "emerge", "-av" ].concat (linuxEmergePackages.split (" ")); ProcessHelper.runCommand ("", "sudo", parameters, false); - LogHelper.println (""); - LogHelper.println ("Setup complete."); + Log.println (""); + Log.println ("Setup complete."); return; } @@ -1183,14 +1183,14 @@ class PlatformSetup { ProcessHelper.runCommand ("", "sudo", parameters, false); - LogHelper.println (""); - LogHelper.println ("Setup complete."); + Log.println (""); + Log.println ("Setup complete."); return; } - LogHelper.println ("Unable to find a supported package manager on your Linux distribution."); - LogHelper.println ("Currently apt-get, yum, dnf, equo, emerge, and pacman are supported."); + Log.println ("Unable to find a supported package manager on your Linux distribution."); + Log.println ("Currently apt-get, yum, dnf, equo, emerge, and pacman are supported."); Sys.exit (1); @@ -1199,11 +1199,11 @@ class PlatformSetup { public static function setupMac ():Void { - LogHelper.println ("\x1b[1mIn order to build native executables for macOS, you must have"); - LogHelper.println ("Xcode installed. Xcode is available from Apple as a free download.\x1b[0m"); - LogHelper.println (""); - LogHelper.println ("\x1b[0;3mNo additional configuration is required.\x1b[0m"); - LogHelper.println (""); + Log.println ("\x1b[1mIn order to build native executables for macOS, you must have"); + Log.println ("Xcode installed. Xcode is available from Apple as a free download.\x1b[0m"); + Log.println (""); + Log.println ("\x1b[0;3mNo additional configuration is required.\x1b[0m"); + Log.println (""); var answer = CLIHelper.ask ("Would you like to visit the download page now?"); @@ -1233,7 +1233,7 @@ class PlatformSetup { } catch (e:Dynamic) {} - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { if (haxePath == null || haxePath == "") { @@ -1304,7 +1304,7 @@ class PlatformSetup { } - if (PlatformHelper.hostPlatform == Platform.MAC) { + if (PlatformHelper.hostPlatform == MAC) { ConfigHelper.writeConfigValue ("MAC_USE_CURRENT_SDK", "1"); @@ -1315,13 +1315,13 @@ class PlatformSetup { public static function setupWindows ():Void { - LogHelper.println ("\x1b[1mIn order to build native executables for Windows, you must have a"); - LogHelper.println ("Visual Studio C++ compiler with \"Windows Desktop\" (Win32) support"); - LogHelper.println ("installed. We recommend using Visual Studio Community, which is"); - LogHelper.println ("available as a free download from Microsoft.\x1b[0m"); - LogHelper.println (""); - LogHelper.println ("\x1b[0;3mNo additional configuration is required.\x1b[0m"); - LogHelper.println (""); + Log.println ("\x1b[1mIn order to build native executables for Windows, you must have a"); + Log.println ("Visual Studio C++ compiler with \"Windows Desktop\" (Win32) support"); + Log.println ("installed. We recommend using Visual Studio Community, which is"); + Log.println ("available as a free download from Microsoft.\x1b[0m"); + Log.println (""); + Log.println ("\x1b[0;3mNo additional configuration is required.\x1b[0m"); + Log.println (""); var answer = CLIHelper.ask ("Would you like to visit the download page now?"); @@ -1336,13 +1336,13 @@ class PlatformSetup { private static function throwPermissionsError () { - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { - LogHelper.println ("Unable to access directory. Perhaps you need to run \"setup\" with administrative privileges?"); + Log.println ("Unable to access directory. Perhaps you need to run \"setup\" with administrative privileges?"); } else { - LogHelper.println ("Unable to access directory. Perhaps you should run \"setup\" again using \"sudo\""); + Log.println ("Unable to access directory. Perhaps you should run \"setup\" again using \"sudo\""); } @@ -1361,7 +1361,7 @@ class PlatformSetup { path = StringTools.replace (path, "\\ ", " "); - if (PlatformHelper.hostPlatform != Platform.WINDOWS && StringTools.startsWith (path, "~/")) { + if (PlatformHelper.hostPlatform != WINDOWS && StringTools.startsWith (path, "~/")) { path = Sys.getEnv ("HOME") + "/" + path.substr (2); @@ -1394,9 +1394,9 @@ class PlatformSetup { if (FileSystem.exists (git)) { - LogHelper.info (LogHelper.accentColor + "Updating \"" + haxelib.name + "\"" + LogHelper.resetColor); + Log.info (Log.accentColor + "Updating \"" + haxelib.name + "\"" + Log.resetColor); - if (PlatformHelper.hostPlatform == Platform.WINDOWS) { + if (PlatformHelper.hostPlatform == WINDOWS) { var path = Sys.getEnv ("PATH"); diff --git a/tools/utils/publish/FirefoxMarketplace.hx b/tools/utils/publish/FirefoxMarketplace.hx index ef46d0f8c..cc58c2f3c 100644 --- a/tools/utils/publish/FirefoxMarketplace.hx +++ b/tools/utils/publish/FirefoxMarketplace.hx @@ -5,7 +5,7 @@ import haxe.crypto.Base64; import haxe.io.Path; import haxe.Json; import lime.tools.helpers.CLIHelper; -import lime.tools.helpers.LogHelper; +import lime.tools.helpers.Log; import lime.tools.helpers.ZipHelper; import lime.tools.helpers.ProcessHelper; import lime.graphics.Image; @@ -18,749 +18,749 @@ import sys.io.File; class FirefoxMarketplace { - - + + private static function compress (project:HXProject):String { - + var outputDirectory = project.app.path + "/firefox"; var source = outputDirectory + "/bin/"; var packagedFile = project.app.file + ".zip"; var destination = outputDirectory + "/dist/" + packagedFile; - + ZipHelper.compress (source, destination); - + return destination; - + } - - + + public static function isValid (project:HXProject):Bool { - + var result = FirefoxHelper.validate (project); - + if (result.errors.length != 0) { - + var errorMsg = "The application cannot be published\n"; - + for (error in result.errors) { - + errorMsg += '\n * ' + error; - + } - - if (LogHelper.verbose) LogHelper.println (""); - LogHelper.error (errorMsg); - + + if (Log.verbose) Log.println (""); + Log.error (errorMsg); + return false; - + } - + return true; - + } - - + + public static function publish (project:HXProject):Void { - + var devServer = project.targetFlags.exists ("dev"); var forceUpload = project.targetFlags.exists ("force"); var answer:Answer; - + /*if (!devServer) { - - LogHelper.println ("In which server do you want to publish your application?"); - LogHelper.println ("\t1. Production server."); - LogHelper.println ("\t2. Development server."); - LogHelper.println ("\tq. Quit."); - + + Log.println ("In which server do you want to publish your application?"); + Log.println ("\t1. Production server."); + Log.println ("\t2. Development server."); + Log.println ("\tq. Quit."); + answer = CLIHelper.ask ("Which server?", ["1", "2", "q"]); - + switch (answer) { - + case CUSTOM (x): - + switch (x) { - + case "2": devServer = true; case "q": Sys.exit (0); - + } - + default: - - + + } - + }*/ - - LogHelper.info ("Checking account..."); - + + Log.info ("Checking account..."); + var defines = project.defines; var existsProd = defines.exists ("FIREFOX_MARKETPLACE_KEY") && defines.exists ("FIREFOX_MARKETPLACE_SECRET"); var existsDev = defines.exists ("FIREFOX_MARKETPLACE_DEV_KEY") && defines.exists ("FIREFOX_MARKETPLACE_DEV_SECRET"); - + if ((!existsProd && !devServer) || (!existsDev && devServer)) { - + setup (false, devServer, cast defines); - + // we need to get all the defines after configuring the account - LogHelper.mute = true; + Log.mute = true; defines = PlatformSetup.getDefines (); - LogHelper.mute = false; - + Log.mute = false; + } - + var baseUrl = devServer ? FirefoxHelper.DEVELOPMENT_SERVER_URL : FirefoxHelper.PRODUCTION_SERVER_URL; var appID:Int = -1; var appSlug:String = ""; var appName = project.meta.title; - + var key = defines.get ("FIREFOX_MARKETPLACE" + (devServer ? "_DEV_" : "_") + "KEY"); var secret = defines.get ("FIREFOX_MARKETPLACE" + (devServer ? "_DEV_" : "_") + "SECRET"); - + var marketplace = new MarketplaceAPI (key, secret, devServer); - + var error = function (r:Dynamic) { - + Reflect.deleteField (r, "error"); - //LogHelper.println (""); - LogHelper.error ((r.customError != null ? r.customError : 'There was an error:\n\n$r')); - + //Log.println (""); + Log.error ((r.customError != null ? r.customError : 'There was an error:\n\n$r')); + }; - + var response:Dynamic = marketplace.getUserAccount (); - + if (response.error) { - + response.customError = "Could not validate your account, please verify your account information"; error (response); - + } - - //LogHelper.println ("OK"); - + + //Log.println ("OK"); + var apps:List = Lambda.filter (marketplace.getUserApps (), function(obj) return appName == Reflect.field (obj.name, "en-US")); - + if (!forceUpload && apps.length > 0) { - + var app = apps.first (); - - LogHelper.println ("This application has already been submitted to the Firefox Marketplace."); + + Log.println ("This application has already been submitted to the Firefox Marketplace."); answer = CLIHelper.ask ("Do you want to open the edit page?", ["y", "n"]); - + if (answer == YES) { - + ProcessHelper.openURL (baseUrl + '/developers/app/${app.slug}/edit'); - + } - + Sys.exit (0); - + } - - //LogHelper.println ("Submitting \"" + appName + "\" to the Firefox " + (devServer ? "development" : "production") + " server"); - + + //Log.println ("Submitting \"" + appName + "\" to the Firefox " + (devServer ? "development" : "production") + " server"); + var packagedFile = compress (project); - + response = marketplace.submitForValidation (packagedFile); - + if (response.error || response.id == null) { - + error (response); - + } - + var uploadID = response.id; - - LogHelper.println (""); - //LogHelper.print ('Server validation ($uploadID)'); - LogHelper.print ("Waiting for server"); - + + Log.println (""); + //Log.print ('Server validation ($uploadID)'); + Log.print ("Waiting for server"); + do { - - LogHelper.print ("."); + + Log.print ("."); response = marketplace.checkValidationStatus (uploadID); Sys.sleep (1); - + } while (!response.processed); - - LogHelper.println (""); - + + Log.println (""); + if (response.valid) { - - //LogHelper.println (" VALID"); - LogHelper.info ("Sending application details..."); + + //Log.println (" VALID"); + Log.info ("Sending application details..."); response = marketplace.createApp (uploadID); - + if (response.error || response.id == null) { - - //LogHelper.println ("ERROR"); + + //Log.println ("ERROR"); error (response); - + } - + appID = response.id; appSlug = response.slug; - - //LogHelper.println ("OK"); - //LogHelper.print ("Updating application information... "); + + //Log.println ("OK"); + //Log.print ("Updating application information... "); response = marketplace.updateAppInformation (appID, project); - + if (response.error) { - - //LogHelper.println ("ERROR"); + + //Log.println ("ERROR"); error (response); - + } - - //LogHelper.println ("OK"); - //LogHelper.println ("Updating screenshots:"); - + + //Log.println ("OK"); + //Log.println ("Updating screenshots:"); + var screenshots:Array = project.config.getArrayString ("firefox-marketplace.screenshots.screenshot", "path"); - + for (i in 0...screenshots.length) { - + response = marketplace.uploadScreenshot (appID, i, screenshots[i]); - LogHelper.println (""); - + Log.println (""); + if (response.error) { - + error (response); - + } - + } - + var urlApp = baseUrl + '/app/$appSlug/'; var devUrlApp = baseUrl + '/developers/app/$appSlug/'; var urlContentRatings = devUrlApp + "content_ratings/edit"; - + var havePayments = project.config.getString ("firefox-marketplace.premium-type", "free") != cast PremiumType.FREE; - - LogHelper.println (""); - LogHelper.info ("Application submitted!"); + + Log.println (""); + Log.info ("Application submitted!"); Sys.sleep (1); - LogHelper.println (""); - LogHelper.info ("Before the application is fully published, you will need to fill out a content"); - LogHelper.info ("rating questionnaire, and send the application for review"); - LogHelper.println (""); + Log.println (""); + Log.info ("Before the application is fully published, you will need to fill out a content"); + Log.info ("rating questionnaire, and send the application for review"); + Log.println (""); var answer = CLIHelper.ask ("Would you like to complete your submission now?"); - + if (answer == YES || answer == ALWAYS) { - - if (LogHelper.verbose) LogHelper.println (""); - ProcessHelper.openURL (urlContentRatings); - + + if (Log.verbose) Log.println (""); + ProcessHelper.openURL (urlContentRatings); + } else { - - LogHelper.println (""); - LogHelper.info ("You can complete your submission later by going to " + devUrlApp); - + + Log.println (""); + Log.info ("You can complete your submission later by going to " + devUrlApp); + } - + /* - LogHelper.println (""); - LogHelper.warn ("Before this application can be reviewed & published:"); - LogHelper.warn ("* You will need to fill the contents rating questionnaire *"); - - if (havePayments) LogHelper.warn ("* You will need to add or link a payment account *"); - - LogHelper.println (""); - LogHelper.println ("1. Open the contents rating questionnaire page."); - LogHelper.println ("2. Open the application edit page."); - LogHelper.println ("3. Open the application listing page."); - LogHelper.println ("q. I'm fine, thanks."); - + Log.println (""); + Log.warn ("Before this application can be reviewed & published:"); + Log.warn ("* You will need to fill the contents rating questionnaire *"); + + if (havePayments) Log.warn ("* You will need to add or link a payment account *"); + + Log.println (""); + Log.println ("1. Open the contents rating questionnaire page."); + Log.println ("2. Open the application edit page."); + Log.println ("3. Open the application listing page."); + Log.println ("q. I'm fine, thanks."); + answer = CLIHelper.ask ("Open the questionnaire now?", ["1", "2", "3", "q"]); - + switch (answer) { - + case CUSTOM (x): - + switch (x) { - - case "1": ProcessHelper.openURL (urlContentRatings); + + case "1": ProcessHelper.openURL (urlContentRatings); case "2": ProcessHelper.openURL (devUrlApp); case "3": ProcessHelper.openURL (urlApp); case _: - + } - + default: - - + + } - - LogHelper.println (""); - LogHelper.println ("Your application listing page is:"); - LogHelper.println ('$urlApp'); - LogHelper.println (""); - LogHelper.println ("Goodbye!");*/ - + + Log.println (""); + Log.println ("Your application listing page is:"); + Log.println ('$urlApp'); + Log.println (""); + Log.println ("Goodbye!");*/ + } else { - - //LogHelper.println (" FAILED"); - LogHelper.println (""); - + + //Log.println (" FAILED"); + Log.println (""); + var errorMsg = "Application failed server validation"; - + var errors:List = Lambda.filter (response.validation.messages, function(m) return m.type == "error"); var n = 1; - + for (error in errors) { - + errorMsg += ('\n * ${error.description.join (" ")}'); - + } - + //errorMsg += "\nPlease refer to the documentation to fix the issues."; marketplace.close (); - LogHelper.error (errorMsg); - + Log.error (errorMsg); + } - + marketplace.close(); - + } - - + + public static function setup (askServer:Bool = true, devServer:Bool = false, defines:Map = null):Void { - + if (defines == null) { - + defines = PlatformSetup.getDefines (); - + } - + var existsProd = defines.exists ("FIREFOX_MARKETPLACE_KEY") && defines.exists ("FIREFOX_MARKETPLACE_SECRET"); var existsDev = defines.exists ("FIREFOX_MARKETPLACE_DEV_KEY") && defines.exists ("FIREFOX_MARKETPLACE_DEV_SECRET"); - + // TODO warning about the override of the account - - LogHelper.println ("You need to link your developer account to publish to the Firefox Marketplace"); + + Log.println ("You need to link your developer account to publish to the Firefox Marketplace"); var answer = CLIHelper.ask ("Would you like to open the developer site now?"); - + if (answer == YES || answer == ALWAYS) { - + var server = ""; - + /*if (askServer) { - - LogHelper.println (""); - LogHelper.println ("First of all you need to select the server you want to setup your account."); - LogHelper.println ("Each server has its own configuration and can't be shared."); - LogHelper.println ("\t1. Production server (" + FirefoxHelper.PRODUCTION_SERVER_URL + ")"); - LogHelper.println ("\t2. Development server (" + FirefoxHelper.DEVELOPMENT_SERVER_URL + ")"); - LogHelper.println("\tq. Cancel"); + + Log.println (""); + Log.println ("First of all you need to select the server you want to setup your account."); + Log.println ("Each server has its own configuration and can't be shared."); + Log.println ("\t1. Production server (" + FirefoxHelper.PRODUCTION_SERVER_URL + ")"); + Log.println ("\t2. Development server (" + FirefoxHelper.DEVELOPMENT_SERVER_URL + ")"); + Log.println("\tq. Cancel"); answer = CLIHelper.ask ("Choose the server to setup your Firefox Marketplace account.", ["1", "2", "q"]); - + } else {*/ - + answer = devServer ? CUSTOM ("2") : CUSTOM ("1"); - + //} - + switch (answer) { - + case CUSTOM ("1"): - + server = FirefoxHelper.PRODUCTION_SERVER_URL; devServer = false; - + case CUSTOM ("2"): - - server = FirefoxHelper.DEVELOPMENT_SERVER_URL; + + server = FirefoxHelper.DEVELOPMENT_SERVER_URL; devServer = true; - + default: Sys.exit (0); - + } - + /*if ((existsProd && !devServer) || (existsDev && devServer)) { - - LogHelper.info (""); - LogHelper.warn ("You will override your account settings!"); + + Log.info (""); + Log.warn ("You will override your account settings!"); answer = CLIHelper.ask ("Are you sure?", ["y", "n"]); - + if (answer == NO) { - + Sys.exit (0); - + } - + }*/ - - LogHelper.println (""); - LogHelper.info ("Opening \"" + server + "/developers/api\"..."); - LogHelper.println (""); - LogHelper.info (" * Create a new account or login"); - LogHelper.info (" * Choose \"Command line\" as the client type then press \"Create\""); - + + Log.println (""); + Log.info ("Opening \"" + server + "/developers/api\"..."); + Log.println (""); + Log.info (" * Create a new account or login"); + Log.info (" * Choose \"Command line\" as the client type then press \"Create\""); + Sys.sleep (3); - if (LogHelper.verbose) LogHelper.println (""); + if (Log.verbose) Log.println (""); ProcessHelper.openURL (server + "/developers/api"); Sys.sleep (2); - - LogHelper.println (""); - LogHelper.info ("\x1b[1mPress any key to continue\x1b[0m"); - + + Log.println (""); + Log.info ("\x1b[1mPress any key to continue\x1b[0m"); + try { - + Sys.stdin ().readLine (); - + } catch (e:Dynamic) { - + Sys.exit (0); - + } - + } - + var key = StringTools.trim (CLIHelper.param ("OAuth Key")); var secret = StringTools.trim (CLIHelper.param ("OAuth Secret")); - - LogHelper.println (""); - + + Log.println (""); + var marketplace = new MarketplaceAPI (key, secret, devServer); var name:String = ""; var account:Dynamic; var valid = false; - + do { - - LogHelper.println ("Checking account..."); + + Log.println ("Checking account..."); account = marketplace.getUserAccount (); - + if (account != null && account.display_name != null) { - + name = account.display_name; valid = true; - + } - + if (!valid) { - - LogHelper.println ("There was a problem connecting to your developer account"); + + Log.println ("There was a problem connecting to your developer account"); answer = CLIHelper.ask ("Would you like to try again?"); - + if (answer == YES) { - - LogHelper.println (""); + + Log.println (""); key = StringTools.trim (CLIHelper.param ("OAuth Key")); secret = StringTools.trim (CLIHelper.param ("OAuth Secret")); - LogHelper.println (""); - + Log.println (""); + marketplace.client.consumer.key = key; marketplace.client.consumer.secret = secret; - + } else { - + marketplace.close (); Sys.exit (0); - + } - + } - + } while (!valid); - - LogHelper.println ("Hello " + name + "!"); - - LogHelper.mute = true; + + Log.println ("Hello " + name + "!"); + + Log.mute = true; defines = PlatformSetup.getDefines (); - LogHelper.mute = false; - + Log.mute = false; + defines.set ("FIREFOX_MARKETPLACE" + (devServer ? "_DEV_" : "_") + "KEY", key); defines.set ("FIREFOX_MARKETPLACE" + (devServer ? "_DEV_" : "_") + "SECRET", secret); - + PlatformSetup.writeConfig (defines.get ("LIME_CONFIG"), defines); - LogHelper.println (""); - + Log.println (""); + } - - + + } class FirefoxHelper { - - + + public static inline var PRODUCTION_SERVER_URL = "https://marketplace.firefox.com"; public static inline var DEVELOPMENT_SERVER_URL = "https://marketplace-dev.allizom.org"; - + private static inline var TITLE_MAX_CHARS = 127; private static inline var MAX_CATEGORIES = 2; private static var MIN_WH_SCREENSHOT = { width: 320, height: 480 }; - - + + private static function isScreenshotValid (path:String):Bool { - + if (FileSystem.exists (path)) { - + var img = Image.fromFile (path); var portrait = img.width >= MIN_WH_SCREENSHOT.width && img.height >= MIN_WH_SCREENSHOT.height; var landscape = img.width >= MIN_WH_SCREENSHOT.height && img.height >= MIN_WH_SCREENSHOT.width; return portrait || landscape; - + } - + return false; - + } - - + + public static function validate (project:HXProject):{ errors:Array, warnings:Array } { - + var errors:Array = []; var warnings:Array = []; - + // We will check if the project has the minimal required fields for publishing to the Firefox Marketplace - + if (project.meta.title == "") { - + errors.push ("You need to have a title\n\n\t\n"); - + } - + if (project.meta.title.length > TITLE_MAX_CHARS) { - + errors.push ("Your title is too long (max " + TITLE_MAX_CHARS + " characters)\n"); - + } - + if (project.config.getString ("firefox-marketplace.description", project.meta.description) == "") { - + errors.push ("You need to have a description\n\n\t\n"); - + } - + if (project.meta.company == "") { - + errors.push ("You need to have a company name\n\n\t\n"); - + } - + if (project.meta.companyUrl == "") { - + errors.push ("You need to have a company URL\n\n\t\n"); - + } - + var categories = project.config.getArrayString ("firefox-marketplace.categories.category", "name"); - + if (categories.length == 0) { - + errors.push ("You need to have at least one category\n\n\t\n\t \n\t \n\t \n\t\n"); - + } else if (categories.length > MAX_CATEGORIES) { - + errors.push ("You cannot have more than two categories"); - + } - + if (project.config.getString ("firefox-marketplace.privacyPolicy") == "") { - + errors.push ("You need to have a privacy policy\n\n\t\n\t Policy detail\n\t\n"); - + } - + if (project.config.getString ("firefox-marketplace.support.email") == "") { - + errors.push ("You need to have a support email address\n\n\t\n\t \n\t\n"); - + } - + var screenshots = project.config.getArrayString ("firefox-marketplace.screenshots.screenshot", "path"); - + if (screenshots.length == 0) { - + errors.push ("You need to have at least one screenshot\n\n\t\n\t \n\t \n\t \n\t\n"); - + } else { - + for (path in screenshots) { - + if (!isScreenshotValid (path)) { - + if (!FileSystem.exists (path)) { - + errors.push ("Screenshot \"" + Path.withoutDirectory (path) + "\" does not exist\n"); - + } else { - + errors.push ("Screenshot \"" + Path.withoutDirectory (path) + "\" must be at least 320 x 480 in size\n"); - + } - - + + } - + } - + } - + return { errors: errors, warnings: warnings }; - + } - - + + } class MarketplaceAPI { - - + + private static inline var API_PATH = "/api/v1/"; - + public var client:OAuthClient; - + private var loader:URLLoader; private var entryPoint:String; - - + + public function new (key:String = null, secret:String = null, devServer:Bool = false) { - + loader = new URLLoader (); - + if (key != null && secret != null) { - + client = new OAuthClient (OAuthVersion.V1, new OAuthConsumer (key, secret)); - + } - + entryPoint = (devServer ? FirefoxHelper.DEVELOPMENT_SERVER_URL : FirefoxHelper.PRODUCTION_SERVER_URL) + API_PATH; - + } - - + + public function checkValidationStatus (uploadID:String):Dynamic { - + var response = load (GET, 'apps/validation/$uploadID/', null); return response; - + } - - + + public function close ():Void { - + loader.close (); - + } - - + + public function createApp (uploadID:String):Dynamic { - + var response = load (POST, 'apps/app/', Json.stringify ({ upload: uploadID })); return response; - + } - - + + public function customRequest (method:URLRequestMethod, path:String, ?data:Dynamic):URLRequest { - + var request:URLRequest; - + if (client == null) { - + request = new URLRequest (entryPoint + path); - + } else { - + request = client.createRequest (method, entryPoint + path); - + } - + request.method = method; request.data = data; request.contentType = "application/json"; - + return request; - + } - - + + public function getUserAccount():Dynamic { - + var response = load (GET, "account/settings/mine/", null); return response; - + } - - + + public function getUserApps ():Array { - + var result:Array = []; var response = load (GET, 'apps/app/', null); - + if (!response.error && response.objects != null) { - + for (obj in cast (response.objects, Array)) { - + result.push (obj); - + } - + } - + return result; - + } - - + + private function load (method:URLRequestMethod, path:String, data:String = null, progressMsg:String = null):Dynamic { - + var response:Dynamic = {}; var status = 0; var request = customRequest (method, path, data); var withProgress = progressMsg != null && progressMsg.length > 0 && data != null; - + var uploadingFunc:URLLoader->Int->Int->Void = null; - + if (withProgress) { - + uploadingFunc = function (l, up, dl) CLIHelper.progress ('$progressMsg', up, data.length); loader.onProgress.add (uploadingFunc); - + } - + loader.onHTTPStatus.add (function (_, s) status = s, true); - + loader.onComplete.add ( function (l) { - + response = Json.parse (l.data); - + if (withProgress) l.onProgress.remove (uploadingFunc); - + } , true); - + loader.load (request); - + response.error = false; - + if (status >= 400) { - + response.error = true; - + } - + return response; - + } - - + + public function submitForValidation (path:String, type:String = "application/zip"):Dynamic { - + var p = new Path (path); var response:Dynamic = {}; - + if (FileSystem.exists (path) && p.ext == "zip") { - + var base = Base64.encode (File.getBytes (path)); var filename = p.file + "." + p.ext; - + var upload = { upload: { type: type, @@ -768,23 +768,23 @@ class MarketplaceAPI { data: base } }; - + response = load (POST, "apps/validation/", Json.stringify (upload), "Uploading:"); - + } else { - + response.error = true; response.customError = 'File $path doesn\'t exist'; - + } - + return response; - + } - - + + public function updateAppInformation (appID:Int, project:HXProject):Dynamic { - + var object = { name: project.meta.title, categories: project.config.getArrayString ("firefox-marketplace.categories.category", "name"), @@ -797,24 +797,24 @@ class MarketplaceAPI { premium_type: project.config.getString ("firefox-marketplace.premium-type", "free"), price: project.config.getString ("firefox-marketplace.config.price", "0.99"), }; - + var response = load (PUT, 'apps/app/$appID/', Json.stringify (object)); return response; - + } - - + + public function uploadScreenshot (appID:Int, position:Int, path:String):Dynamic { - + var response:Dynamic = {}; - + if (FileSystem.exists (path)) { - + var p = new Path (path); var type = p.ext == "png" ? "image/png" : "image/jpeg"; var base = Base64.encode (File.getBytes (path)); var filename = p.file + "." + p.ext; - + var screenshot = { position: position, file: { @@ -823,40 +823,40 @@ class MarketplaceAPI { data: base, } }; - - response = load (POST, 'apps/app/$appID/preview/', Json.stringify (screenshot), 'Uploading screenshot:'); - + + response = load (POST, 'apps/app/$appID/preview/', Json.stringify (screenshot), 'Uploading screenshot:'); + } else { - + response.error = true; response.customError = 'File "$path" does not exist'; - + } - + return response; - + } - - + + } @:enum abstract DeviceType(String) { - + var FIREFOXOS = "firefoxos"; var DESKTOP = "desktop"; var MOBILE = "mobile"; var TABLET = "tablet"; - + } @:enum abstract PremiumType(String) { - + var FREE = "free"; var FREE_INAPP = "free-inapp"; var PREMIUM = "premium"; var PREMIUM_INAPP = "premium-inapp"; var OTHER = "other"; - + } \ No newline at end of file