From 38c0ddddad7056567fd4c0af7746bd3036c95b6b Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Fri, 6 Jun 2025 09:17:59 +0330 Subject: [PATCH] cleanup all js Helper apps and Create an MQL Module Helper and do all requirements inside it ... --- Documents/JsModules/mqlHelper.js | 19 + Documents/JsModules/prepareXCATBEA.js | 35 ++ Documents/JsModules/x-mql-project.tools.js | 494 +++++++++++++++++++++ MQL5.code-workspace | 3 +- cleanupEX.js | 52 --- compile.cmd | 2 +- compile.js | 443 ------------------ compileEA.js | 127 ------ mqlHelper.js | 19 + pack.js | 146 ------ package.json | 27 +- prepareXCATBEA.js | 35 ++ x-mql-project.tools.js | 494 +++++++++++++++++++++ 13 files changed, 1108 insertions(+), 788 deletions(-) create mode 100644 Documents/JsModules/mqlHelper.js create mode 100644 Documents/JsModules/prepareXCATBEA.js create mode 100644 Documents/JsModules/x-mql-project.tools.js delete mode 100644 cleanupEX.js delete mode 100644 compile.js delete mode 100644 compileEA.js create mode 100644 mqlHelper.js delete mode 100644 pack.js create mode 100644 prepareXCATBEA.js create mode 100644 x-mql-project.tools.js diff --git a/Documents/JsModules/mqlHelper.js b/Documents/JsModules/mqlHelper.js new file mode 100644 index 00000000..8fe4e41b --- /dev/null +++ b/Documents/JsModules/mqlHelper.js @@ -0,0 +1,19 @@ +/** + * XMQL Helper CLI Tools ... + * a module for handle MQL5 Commands running ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +// Import Requirements ... +const XProjectTools = require("./x-mql-project.tools"); + +// +// Read Command Arguments ... +let cmdName = process.argv[2]; + +// +XProjectTools.runCommand(cmdName); diff --git a/Documents/JsModules/prepareXCATBEA.js b/Documents/JsModules/prepareXCATBEA.js new file mode 100644 index 00000000..797e2134 --- /dev/null +++ b/Documents/JsModules/prepareXCATBEA.js @@ -0,0 +1,35 @@ +// +// Import Requirements ... +const XProjectTools = require("./x-mql-project.tools"); + +// +// define constants ... +const projectName = "XCATBEA"; + +// +// Projects Resources ... +const projectResources = [ + "Libraries/*", // Required Libraries + "Classes/*", // Required Classes + "XCATBEA/*", // XCATBEA Projects ... + "Indicators/x-saherelm.x121.xcatb", // Required Indicators + "Helpers/x-saherelm.x121.xcatb.helper", // Indicator's Helpers Classes + "Experts/x-saherelm.x121.xcatb.ea", // Expert Advisers +]; + +// +run(); + +/** + * Main Project Function ... + */ +async function run() { + // + await XProjectTools.prepareProject( + projectName, + projectResources + ); +} + + + diff --git a/Documents/JsModules/x-mql-project.tools.js b/Documents/JsModules/x-mql-project.tools.js new file mode 100644 index 00000000..4a507a48 --- /dev/null +++ b/Documents/JsModules/x-mql-project.tools.js @@ -0,0 +1,494 @@ +/** + * XProject Tools Module ... + * a module for handle MQL5 Projects Compile and Packing ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +// Import Requirements ... +const execSync = require("child_process").execSync; +const XFileTools = require("./Documents/JsModules/x-file.tools"); +const XShellTools = require("./Documents/JsModules/x-shell.tools"); +const XColorTools = require("./Documents/JsModules/x-color.tools"); +const XTypeTools = require("./Documents/JsModules/x-type-detector.tools"); + +// +// Definitions ... +const packsPath = XFileTools.joinPath(".", "Packs"); +const workspacePaths = [ + "Classes", // Required Classes + "Experts", // Expert Advisers + "Helpers", // Indicator's Helpers Classes + "Indicators", // Required Indicators + "Libraries", // Required Libraries + "XCATBEA", // XCATBEA Projects ... +]; + +// +//#region Tools ... + +/** + * Handle Compile and Pack Projects ... + * + * @param {string} projectName + * @param {string[]} resources + * @param {boolean} forceCleanup + * @param {boolean} forceCompileIndicators + */ +async function prepareProject( + projectName = "", + resources = [], + forceCleanup = true, + forceCompileIndicators = true +) { + // + // Check Resources Has Child ... + let isValidArgs = + resources.length > 0 && + XTypeTools.isArray(resources); + if (!isValidArgs) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Invalid Resource List ...", XColorTools.COLOR_NAMES.Red) + ); + } + + // + // Check Project Name is Valid ... + isValidArgs = + projectName.length > 0 && + XTypeTools.isString(projectName); + if (!isValidArgs) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Empty Project Name ...", XColorTools.COLOR_NAMES.Red) + ); + } + + // + // Extract Required to Compile Resources List ... + let compileList = await extractResources(resources, true); + if (!compileList || compileList.length == 0) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Resource List Extraction to Compile Failed ...", XColorTools.COLOR_NAMES.Red) + ); + + // + return; + } + + // + // Compile Resources Files ... + for (const f of compileList) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to Compile: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) + ); + + // + await recursiveTriesToCompileFile(f, 0); + } + + // + // Extract Required to Pack Resources List ... + let packList = await extractResources(resources, false); + if (!packList || packList.length == 0) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Resource List Extraction to Pack Failed ...", XColorTools.COLOR_NAMES.Red) + ); + + // + return; + } + + // + // Prepare Pack Folder Exists ... + let isExists = XFileTools.isDirectoryExists(packsPath); + if (!isExists) { + XFileTools.createDirectory(packsPath); + } + + // + // Check Folder Exists or not ... + // if Exists Remove it ... + // Create Project Folder on Packs ... + const prjFolderOnPacks = XFileTools.joinPath(packsPath, projectName); + isExists = XFileTools.isDirectoryExists(prjFolderOnPacks); + if (isExists) { + await XFileTools.removeDirectory(prjFolderOnPacks, true); + } + XFileTools.createDirectory(prjFolderOnPacks); + + // + // Loop through Files ... + for (const f of packList) { + // + // Prepare Destination Path ... + const fBasePath = XFileTools.basename(f); + let fDestPath = f.replace(fBasePath, ""); + fDestPath = fDestPath.substring(0, fDestPath.length - 1); + fDestPath = XFileTools.joinPath(prjFolderOnPacks, fDestPath); + + // + const isFDestPathExists = XFileTools.isDirectoryExists(fDestPath); + if (!isFDestPathExists) { + XFileTools.createDirectory(fDestPath); + } + + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to copy: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue), + XColorTools.applyForegroundColor(" to : ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(fDestPath, XColorTools.COLOR_NAMES.Magenta) + ); + + // + let result = await XFileTools.copyFile(f, fDestPath); + if (result) { + // + const msg = "copy successfully ..."; + console.log( + XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green) + ); + } else { + // + const msg = "copy failed ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + } + + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Project: ", XColorTools.COLOR_NAMES.Green), + XColorTools.applyForegroundColor(projectName, XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(" Compiled and Packed Successfully ...", XColorTools.COLOR_NAMES.Green), + ); + + // + // Cleanup WorkSpace if Provided ... + if (forceCleanup) { + await cleanupWorkSpace(); + } + + // + // Compile Indicators ... + if (forceCompileIndicators) { + await compile("Indicators"); + } +} + +/** + * Extract required Files List ... + * + * @param {boolean} forCompile + * + * @returns Promise + */ +async function extractResources( + resources = [], + forCompile = true +) { + // + let result = []; + + // + // Loop Through Project Resources and Extract Files List to Compile ... + for (const resource of resources) { + // + // Prepare Normalized Resource Path ... + let resourcePath = XFileTools.joinPath(".", resource); + + // + // Handle Wild Card Resources ... + if (resourcePath.endsWith("//*") || + resourcePath.endsWith("\\*")) { + // + resourcePath = resourcePath.substring(0, resourcePath.length - 2); + const files = await XFileTools.extractFiles( + resourcePath, + forCompile ? [".mq5", ".mq4"] : [".ex5", ".ex4"] + ); + + // + result = result.concat(files); + } + // + // Handle Direct File Resources ... + else { + // + // Check MQL 5 Version ... + let fileResourcePath = resourcePath + (forCompile ? ".mq5" : ".ex5"); + + // + // Check File Exists ... + let isExists = XFileTools.isFileExists(fileResourcePath); + if (!isExists) { + // + // Check MQL 4 Version ... + fileResourcePath = resourcePath + (forCompile ? ".mq4" : ".ex4"); + isExists = XFileTools.isFileExists(fileResourcePath); + } + + // + // Add File Path to Files List if Exists ... + if (isExists) { + result.push(fileResourcePath); + } + } + } + + // + return result; +} + +/** + * try to compile a file ... + * @param {string} f + * @param {number} numberOfTries + */ +async function recursiveTriesToCompileFile(f = "", numberOfTries = 0) { + // + let result = await handleFileCompile(f); + if (result) { + // + const msg = "compiled successfully ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green)); + return result; + } else { + // + if (numberOfTries < 10) { + // + numberOfTries++; + + // + const msg = "retry (" + (numberOfTries + 1) + ") ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.LightMagenta)); + await recursiveTriesToCompileFile(f, numberOfTries); + } else { + // + const msg = "failed ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + + // + return false; + } + } +} + +/** + * execute compile task on Specific File ... + * @param {string} f file path to Execute Compile task ... + * @returns + */ +async function handleFileCompile(f = "") { + // + let result = false; + + // + let exResult = await compileMQLFile(f); + if (exResult.includes("0 errors")) { + result = true; + } else { + result = false; + } + + // + return result; +} + +/** + * Compile Specific MQL File ... + * + * @param {string} path MQL file path ... + * @returns + */ +async function compileMQLFile(path = "") { + // + // Check File Exists ... + const isExists = XFileTools.isFileExists(path); + if (!isExists) { + // + const msg = "file not found ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + + // + const ext = XFileTools.getFileExtension(path); + if (ext !== ".mq5" && ext !== "mq4") { + // + const msg = "invalid file extension ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + + // + const cwd = __dirname; + const cmd = "compile.cmd " + path; + + // + const result = await XShellTools.execute(cmd, cwd); + return result; +} + +/** + * Run Specified Command in workspace ... + * + * @param {string} cmd + * @returns + */ +async function runCommand(cmd = "") { + // + // Validate Args ... + let isValidArgs = cmd.length > 0 && + XTypeTools.isString(cmd); + + // + // Validate Commands ... + if (isValidArgs) { + // + // Check Available Commands ... + isValidArgs = + cmd === "*" || + cmd === "cleanup" || + workspacePaths.includes(cmd) || + workspacePaths.map(x => x.toLowerCase(x)).includes(cmd.toLowerCase()); + } + if (!isValidArgs) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Invalid Command ...", XColorTools.COLOR_NAMES.Red) + ); + } + + // + // Compile ... + if (cmd == "*") { + await compileWorkSpace(); + } else if (cmd == "cleanup") { + await cleanupWorkSpace(); + } else { + // + // Select Workspace to Compile ... + const folder = workspacePaths + .find(x => x.toLowerCase() === cmd.toLowerCase()); + isValidArgs = + XTypeTools.isString(folder) && + folder.length > 0; + if (!isValidArgs) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Invalid Command ...", XColorTools.COLOR_NAMES.Red) + ); + } + + // + // Extract Required to Compile Resources List ... + let compileList = await XFileTools.extractFiles( + folder, + [".mq5", ".mq4"] + ); + if (!compileList || compileList.length == 0) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Extraction to Compile Failed ...", XColorTools.COLOR_NAMES.Red) + ); + + // + return; + } + + // + // Compile Resources Files ... + for (const f of compileList) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to Compile: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) + ); + + // + await recursiveTriesToCompileFile(f, 0); + } + } +} + +/** + * Cleanup Workspace compiled files ... + */ +async function cleanupWorkSpace() { + // + for (const path of workspacePaths) { + // + const fSourcePath = XFileTools.joinPath(".", path); + const filesToRemove = await XFileTools.extractFiles(fSourcePath, [".ex5", ".ex4"]); + for (const f of filesToRemove) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to Remove: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) + ); + + // + let result = await XFileTools.removeFile(f); + if (result) { + // + const msg = "removed successfully ..."; + console.log( + XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green) + ); + } else { + // + const msg = "removed failed ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + } + } +} + +/** + * Compile Workspace ... + */ +async function compileWorkSpace() { + // + for (const path of workspacePaths) { + await runCommand(path); + } +} +//#endregion + +// +//#region Module Exports ... +module.exports = { + extractResources, + recursiveTriesToCompileFile, + handleFileCompile, + compileMQLFile, + runCommand, + cleanupWorkSpace, + compileWorkSpace, + prepareProject +} +//#endregion \ No newline at end of file diff --git a/MQL5.code-workspace b/MQL5.code-workspace index 9ae992df..04efa605 100644 --- a/MQL5.code-workspace +++ b/MQL5.code-workspace @@ -7,7 +7,8 @@ "settings": { "C_Cpp.default.includePath": [ "c:\\Users\\SaherElm\\AppData\\Roaming\\MetaQuotes\\Terminal\\D0E8209F77C8CF37AD8BF550E51FF075\\MQL5\\Include\\Include", - "c:\\Users\\SaherElm\\AppData\\Roaming\\MetaQuotes\\Terminal\\D0E8209F77C8CF37AD8BF550E51FF075\\MQL5\\Include" + "c:\\Users\\SaherElm\\AppData\\Roaming\\MetaQuotes\\Terminal\\D0E8209F77C8CF37AD8BF550E51FF075\\MQL5\\Include", + "c:\\Users\\SaherElm\\AppData\\Roaming\\MetaQuotes\\Terminal\\572C4A1F743028C65C8BA0B780030F0D\\MQL5\\Include" ], "C_Cpp.clang_format_style": "{ BasedOnStyle: Microsoft, UseTab: Never, IndentWidth: 4, TabWidth: 4, ColumnLimit: 0}", "files.associations": { diff --git a/cleanupEX.js b/cleanupEX.js deleted file mode 100644 index e4c0e5f2..00000000 --- a/cleanupEX.js +++ /dev/null @@ -1,52 +0,0 @@ -// -// Import Requirements ... -const execSync = require("child_process").execSync; -const XFileTools = require("./Documents/JsModules/x-file.tools"); -const XShellTools = require("./Documents/JsModules/x-shell.tools"); -const XColorTools = require("./Documents/JsModules/x-color.tools"); - -// -handleCleanup(); -async function handleCleanup() { - // - var foldersPath = [ - "Classes", // Required Classes - "Experts", // Expert Advisers - "Helpers", // Indicator's Helpers Classes - "Indicators", // Required Indicators - "Libraries", // Required Libraries - "Parsers", // Strategies Filters based on Conditions - "Strategies", // Strategies Classes which Provides Signals - "XCATBEA", // XCATBEA Projects ... - ]; - - // - for (const path of foldersPath) { - // - const fSourcePath = XFileTools.joinPath(".", path); - const filesToRemove = await XFileTools.extractFiles(fSourcePath, [".ex5", ".ex4"]); - for (const f of filesToRemove) { - // - // Log ... - console.log( - XColorTools.applyForegroundColor("try to Remove: ", XColorTools.COLOR_NAMES.Yellow), - XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) - ); - - // - let result = await XFileTools.removeFile(f); - if (result) { - // - const msg = "removed successfully ..."; - console.log( - XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green) - ); - } else { - // - const msg = "removed failed ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - } - } -} \ No newline at end of file diff --git a/compile.cmd b/compile.cmd index 4fc256cf..0015d258 100644 --- a/compile.cmd +++ b/compile.cmd @@ -1,6 +1,6 @@ @echo off - set METAEDITOR="C:\Program Files\MetaTrader 5\MetaEditor64.exe" + set METAEDITOR="C:\Program Files\MetaTrader 5 Main\MetaEditor64.exe" set "LOGFILE=%~dpn1.log" if "%~1"=="" ( diff --git a/compile.js b/compile.js deleted file mode 100644 index e45be901..00000000 --- a/compile.js +++ /dev/null @@ -1,443 +0,0 @@ -// -// Import Requirements ... -const execSync = require("child_process").execSync; -const XFileTools = require("./Documents/JsModules/x-file.tools"); -const XShellTools = require("./Documents/JsModules/x-shell.tools"); -const XColorTools = require("./Documents/JsModules/x-color.tools"); - -// -// define constants ... -const projectsPath = XFileTools.joinPath(".", "Projects"); -const packsPath = XFileTools.joinPath(".", "Packs"); -const excludeWorkspaceFolders = [ - "BKP", - "Documents", - "Images", - "Includes", - "Logs", - "Packs", - "Profiles", - "Projects", - "Scripts", - "Services", - "Shared Projects", - // - // Exclude Defaults ... - "Examples", - "Free Indicators", - "Advisors", - "Free Robots" -]; - -// -// Read Command Arguments ... -let projectName = process.argv[2]; -let doPackProject = process.argv[3] || false; - -// -// Make Decission to what to Do based on given args ... -if (!projectName || - projectName == "" || - projectName.length == 0) { - // - // Compile Whole MQL Workspace ... - doPackProject = false; - const workSpacePath = XFileTools.joinPath(".", __dirname); - - // - doWorkspaceCompile(workSpacePath); -} else if (projectName == "--experts" || projectName == "**experts") { - // - // Compile Experts on Workspace ... - doPackProject = false; - const workSpacePath = XFileTools.joinPath(".", __dirname, "Experts"); - - // - doWorkspaceCompile(workSpacePath); -} else if (projectName == "--helpers" || projectName == "**helpers") { - // - // Compile Helpers on Workspace ... - doPackProject = false; - const workSpacePath = XFileTools.joinPath(".", __dirname, "Helpers"); - - // - doWorkspaceCompile(workSpacePath); -} else if (projectName == "--classes" || projectName == "**classes") { - // - // Compile Classes on Workspace ... - doPackProject = false; - const workSpacePath = XFileTools.joinPath(".", __dirname, "Classes"); - - // - doWorkspaceCompile(workSpacePath); -} else if (projectName == "--indicators" || projectName == "**indicators") { - // - // Compile Indicators on Workspace ... - doPackProject = false; - const workSpacePath = XFileTools.joinPath(".", __dirname, "Indicators"); - - // - doWorkspaceCompile(workSpacePath); -} else if (projectName == "--libraries" || projectName == "**libraries") { - // - // Compile Libraries on Workspace ... - doPackProject = false; - const workSpacePath = XFileTools.joinPath(".", __dirname, "Libraries"); - - // - doWorkspaceCompile(workSpacePath); -}else if (projectName == "--strategies" || projectName == "**strategies") { - // - // Compile Libraries on Workspace ... - doPackProject = false; - const workSpacePath = XFileTools.joinPath(".", __dirname, "Strategies"); - - // - doWorkspaceCompile(workSpacePath); -}else if (projectName == "--parsers" || projectName == "**parsers") { - // - // Compile Libraries on Workspace ... - doPackProject = false; - const workSpacePath = XFileTools.joinPath(".", __dirname, "Parsers"); - - // - doWorkspaceCompile(workSpacePath); -} else { - // - // Compile Specific Projects ... - // - // Prepare Project Folder Path ... - const prjPath = XFileTools.joinPath(projectsPath, projectName); - - // - // Check Project Folder Exists ... - const isProjectFolderExists = XFileTools.isDirectoryExists(prjPath); - if (!isProjectFolderExists) { - // - const msg = "Project doesn't Exists ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - - // - // Call Handler Function ... - doProjectCompile(prjPath); -} - -// -async function doProjectCompile(path = "") { - // - let result = await handleProjectCompile(path); - if (result && doPackProject) { - result = await handleProjectPack(path); - } -} - -// -async function doWorkspaceCompile(path = "") { - // - let mustCompileFiles = await readMQLFiles(path); - - // - if (mustCompileFiles && mustCompileFiles.length > 0) { - // - // Loop through items ... - for (const f of mustCompileFiles) { - // - // Check Exclude ... - const fBaseName = XFileTools.basename(f); - let fPath = f.replace(fBaseName, ""); - let isExclude = false; - for (const e of excludeWorkspaceFolders) { - // - isExclude = fPath.includes(e); - if (isExclude) { - break; - } - } - - // - if (isExclude) { - continue; - } - - // - // Log ... - console.log( - XColorTools.applyForegroundColor("try to compile: ", XColorTools.COLOR_NAMES.Yellow), - XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) - ); - - // - const result = await compileMQLFile(f); - - // - if (result.includes("0 errors")) { - // - const msg = "compiled successfully ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green)); - } else { - // - const msg = "failed ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - } - - // - return true; - } - - // - return false; -} - -/** - * read all content in project path and compile it one by one ... - * - * @param {string} path Project Path ... - */ -async function handleProjectCompile(path = "") { - // - let mustCompileFiles = await readMQLFiles(path); - - // - if (mustCompileFiles && mustCompileFiles.length > 0) { - // - // Loop through items ... - for (const f of mustCompileFiles) { - // - // Log ... - console.log( - XColorTools.applyForegroundColor("try to compile: ", XColorTools.COLOR_NAMES.Yellow), - XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) - ); - - // - const result = await compileMQLFile(f); - - // - if (result.includes("0 errors")) { - // - const msg = "compiled successfully ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green)); - } else { - // - const msg = "failed ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - } - - // - return true; - } - - // - return false; -} - -/** - * Pack Compiled Project ... - * - * @param {string} path Project Path ... - */ -async function handleProjectPack(path = "") { - // - const projectName = XFileTools.basename(path); - - // - // check packs exists or not ... - const isPacksExists = XFileTools.isDirectoryExists(packsPath); - if (!isPacksExists) { - XFileTools.createDirectory(packsPath); - } - - // - // Reading Compiled Files ... - const mustCopyFiles = await readEXTFiles(path); - if (!mustCopyFiles || mustCopyFiles.length == 0) { - return false; - } - - // - const prjPackPath = XFileTools.joinPath(packsPath, projectName); - - // - // Check Project Packs Folder ... - const isProjectPackExists = XFileTools.isDirectoryExists(prjPackPath); - if (isProjectPackExists) { - await XFileTools.removeDirectory(prjPackPath, true); - } - - // - // Create Empty Project Folder on Pack ... - XFileTools.createDirectory(prjPackPath); - - // - // Loop through Files ... - for (const f of mustCopyFiles) { - // - // Prepare Destination Path ... - const fBasePath = XFileTools.basename(f); - let fDestPath = f.replace(fBasePath, "") - .replace(projectsPath, packsPath); - fDestPath = fDestPath.substring(0, fDestPath.length - 1); - - // - const isFDestPathExists = XFileTools.isDirectoryExists(fDestPath); - if (!isFDestPathExists) { - XFileTools.createDirectory(fDestPath); - } - - // - // Log ... - console.log( - XColorTools.applyForegroundColor("try to copy: ", XColorTools.COLOR_NAMES.Yellow), - XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue), - XColorTools.applyForegroundColor(" to : ", XColorTools.COLOR_NAMES.Yellow), - XColorTools.applyForegroundColor(fDestPath, XColorTools.COLOR_NAMES.Magenta) - ); - - // - let result = await XFileTools.copyFile(f, fDestPath); - if (result) { - // - const msg = "copy successfully ..."; - console.log( - XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green) - ); - } else { - // - const msg = "copy failed ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - } - - // - return true; -} - -/** - * Extract Project MQL files ... - * - * @param {string} path Folder Path ... - * @returns - */ -async function readMQLFiles(path = "") { - // - const result = await extractFiles(path, [".mq5", ".mq4"]); - - // - return result; -} - -/** - * Extract Project Compiled files ... - * - * @param {string} path Folder Path ... - * @returns - */ -async function readEXTFiles(path = "") { - // - const result = await extractFiles(path, [".ex5", ".ex4"]); - - // - return result; -} - -/** - * Compile Specific MQL File ... - * - * @param {string} path MQL file path ... - * @returns - */ -async function compileMQLFile(path = "") { - // - // Check File Exists ... - const isExists = XFileTools.isFileExists(path); - if (!isExists) { - // - const msg = "file not found ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - - // - const ext = XFileTools.getFileExtension(path); - if (ext !== ".mq5" && ext !== "mq4") { - // - const msg = "invalid file extension ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - - // - const cwd = __dirname; - const cmd = "compile.cmd " + path; - - // - const result = await XShellTools.execute(cmd, cwd); - return result; -} - - -/** - * Extract Specific files from a folder and it's content ... - * - * @param {string} path Folder Path ... - * @returns - */ -async function extractFiles(path = "", ext = []) { - // - const result = []; - - // - if (!ext || ext.length == 0) { - return result; - } - - // - const pathContent = await XFileTools.getDirectoryContents(path); - if (!pathContent || pathContent.length == 0) { - return result; - } - - // - // Loop through Content ... - for (const c of pathContent) { - // - // Prepare full path ... - const cPath = XFileTools.joinPath(path, c); - - // - // check content path is file or not ... - const isCFile = XFileTools.isFileExists(cPath); - const isCDirectory = XFileTools.isDirectoryExists(cPath); - if (isCFile) { - // - // Check it is MQL file or not ... - const cExt = XFileTools.getFileExtension(cPath); - if (ext.includes(cExt)) { - result.push(cPath); - } - } else if (isCDirectory) { - // - const destFolderName = XFileTools.basename(cPath); - const isExcluded = excludeWorkspaceFolders.includes(destFolderName); - if (isExcluded) { - continue; - } - - // - const cFiles = await extractFiles(cPath, ext); - if (cFiles && cFiles.length > 0) { - result.push(...cFiles); - } - } - } - - // - return result; -} diff --git a/compileEA.js b/compileEA.js deleted file mode 100644 index 0859e3d6..00000000 --- a/compileEA.js +++ /dev/null @@ -1,127 +0,0 @@ -// -// Import Requirements ... -const execSync = require("child_process").execSync; -const XFileTools = require("./Documents/JsModules/x-file.tools"); -const XShellTools = require("./Documents/JsModules/x-shell.tools"); -const XColorTools = require("./Documents/JsModules/x-color.tools"); - -// -handleCompile(); -async function handleCompile() { - // - var foldersPath = [ - "Libraries", // Required Libraries - "Classes", // Required Classes - "Indicators", // Required Indicators - "Helpers", // Indicator's Helpers Classes - "Parsers", // Strategies Filters based on Conditions - "Strategies", // Strategies Classes which Provides Signals - "Experts", // Expert Advisers - "XCATBEA", // XCATBEA Projects ... - ]; - - // - for (const path of foldersPath) { - // - const fSourcePath = XFileTools.joinPath(".", path); - const filesToCompile = await XFileTools.extractFiles(fSourcePath, [".mq5", ".mq4"]); - for (const f of filesToCompile) { - // - // Log ... - console.log( - XColorTools.applyForegroundColor("try to Compile: ", XColorTools.COLOR_NAMES.Yellow), - XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) - ); - - // - await recursiveTriesToCompileFile(f, 0); - } - } -} - -/** - * try to compile a file ... - * @param {string} f - * @param {number} numberOfTries - */ -async function recursiveTriesToCompileFile(f = "", numberOfTries = 0) { - // - let result = await handleFileCompile(f); - if (result) { - // - const msg = "compiled successfully ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green)); - } else { - // - if (numberOfTries < 10) { - // - numberOfTries++; - - // - const msg = "retry (" + (numberOfTries + 1) + ") ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.LightMagenta)); - await recursiveTriesToCompileFile(f, numberOfTries); - } else { - // - const msg = "failed ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - } -} - -/** - * execute compile task on Specific File ... - * @param {string} f file path to Execute Compile task ... - * @returns - */ -async function handleFileCompile(f = "") { - // - let result = false; - - // - let exResult = await compileMQLFile(f); - if (exResult.includes("0 errors")) { - result = true; - } else { - result = false; - } - - // - return result; -} - -/** - * Compile Specific MQL File ... - * - * @param {string} path MQL file path ... - * @returns - */ -async function compileMQLFile(path = "") { - // - // Check File Exists ... - const isExists = XFileTools.isFileExists(path); - if (!isExists) { - // - const msg = "file not found ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - - // - const ext = XFileTools.getFileExtension(path); - if (ext !== ".mq5" && ext !== "mq4") { - // - const msg = "invalid file extension ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - - // - const cwd = __dirname; - const cmd = "compile.cmd " + path; - - // - const result = await XShellTools.execute(cmd, cwd); - return result; -} diff --git a/mqlHelper.js b/mqlHelper.js new file mode 100644 index 00000000..8fe4e41b --- /dev/null +++ b/mqlHelper.js @@ -0,0 +1,19 @@ +/** + * XMQL Helper CLI Tools ... + * a module for handle MQL5 Commands running ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +// Import Requirements ... +const XProjectTools = require("./x-mql-project.tools"); + +// +// Read Command Arguments ... +let cmdName = process.argv[2]; + +// +XProjectTools.runCommand(cmdName); diff --git a/pack.js b/pack.js deleted file mode 100644 index 52dc8a9c..00000000 --- a/pack.js +++ /dev/null @@ -1,146 +0,0 @@ -// -// Import Requirements ... -const execSync = require("child_process").execSync; -const XFileTools = require("./Documents/JsModules/x-file.tools"); -const XShellTools = require("./Documents/JsModules/x-shell.tools"); -const XColorTools = require("./Documents/JsModules/x-color.tools"); - -// -const packsPath = XFileTools.joinPath(".", "Packs"); - -// -handlePack(); -async function handlePack() { - // - var date = new Date(); - - // - var year = date.getFullYear(); - var month = date.getMonth() + 1; - var day = date.getDate(); - var hour = date.getHours(); - var min = date.getMinutes(); - - // - var folderName = year.toString() + "-" + month.toString() + "-" + day.toString() + "(" + hour.toString() + "_" + min.toString() + ")"; - - // - const prjBasePath = XFileTools.joinPath(packsPath, folderName); - - // - const prjBaseSourcePath = XFileTools.joinPath(prjBasePath, "Source"); - const prjBaseCompiledPath = XFileTools.joinPath(prjBasePath, "Compile"); - - // - const isPacksExists = XFileTools.isDirectoryExists(packsPath); - if (!isPacksExists) { - XFileTools.createDirectory(packsPath); - } - - // - const isProjectExists = XFileTools.isDirectoryExists(prjBasePath); - if (!isProjectExists) { - XFileTools.createDirectory(prjBasePath); - } - - // - const isPrjBaseSourcePathExists = XFileTools.isDirectoryExists(prjBaseSourcePath); - if (!isPrjBaseSourcePathExists) { - XFileTools.createDirectory(prjBaseSourcePath); - } - - // - const isPrjBaseCompiledPathExists = XFileTools.isDirectoryExists(prjBaseCompiledPath); - if (!isPrjBaseCompiledPathExists) { - XFileTools.createDirectory(prjBaseCompiledPath); - } - - // - var foldersPath = [ - "Classes", // Required Classes - "Experts", // Expert Advisers - "Helpers", // Indicator's Helpers Classes - "Indicators", // Required Indicators - "Libraries", // Required Libraries - "Parsers", // Strategies Filters based on Conditions - "Strategies", // Strategies Classes which Provides Signals - ]; - - // - for (const path of foldersPath) { - // - const fSourcePath = XFileTools.joinPath(".", path); - - // - // Source Copy ... - let fDestPath = XFileTools.joinPath(prjBaseSourcePath, path); - - // - // Log ... - console.log( - XColorTools.applyForegroundColor("try to copy: ", XColorTools.COLOR_NAMES.Yellow), - XColorTools.applyForegroundColor(path, XColorTools.COLOR_NAMES.Blue), - XColorTools.applyForegroundColor(" to : ", XColorTools.COLOR_NAMES.Yellow), - XColorTools.applyForegroundColor(prjBaseSourcePath, XColorTools.COLOR_NAMES.Magenta) - ); - - // - // Copy Folder ... - let result = await XFileTools.copyFolder(fSourcePath, prjBaseSourcePath); - if (result) { - // - const msg = "copy successfully ..."; - console.log( - XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green) - ); - } else { - // - const msg = "copy failed ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - - // - // Cleanup Folder ... - const sourceFilesToRemove = await XFileTools.extractFiles(fDestPath, [".ex5", ".ex4"]); - for (const f of sourceFilesToRemove) { - await XFileTools.removeFile(f); - } - - // - // Compile Copy ... - fDestPath = XFileTools.joinPath(prjBaseCompiledPath, path); - - // - // Log ... - console.log( - XColorTools.applyForegroundColor("try to copy: ", XColorTools.COLOR_NAMES.Yellow), - XColorTools.applyForegroundColor(path, XColorTools.COLOR_NAMES.Blue), - XColorTools.applyForegroundColor(" to : ", XColorTools.COLOR_NAMES.Yellow), - XColorTools.applyForegroundColor(prjBaseCompiledPath, XColorTools.COLOR_NAMES.Magenta) - ); - - // - // Copy Folder ... - result = await XFileTools.copyFolder(fSourcePath, prjBaseCompiledPath); - if (result) { - // - const msg = "copy successfully ..."; - console.log( - XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green) - ); - } else { - // - const msg = "copy failed ..."; - console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); - throw msg; - } - - // - // Cleanup Folder ... - const compileFilesToRemove = await XFileTools.extractFiles(fDestPath, [".mq5", ".mq4"]); - for (const f of compileFilesToRemove) { - await XFileTools.removeFile(f); - } - } -} \ No newline at end of file diff --git a/package.json b/package.json index 62ade3e0..f6dc8c20 100644 --- a/package.json +++ b/package.json @@ -8,24 +8,15 @@ "aaa": "|----------|", "aab": "| Commons |", "aac": "|----------|", - "compile": "node compile.js", - "pack": "node pack.js", - "cleanupEx": "node cleanupEx.js", - "compileEA": "node compileEA.js", - "compileExperts": "npm run compile **experts", - "compileLibraries": "npm run compile **libraries", - "compileHelpers": "npm run compile **helpers", - "compileClasses": "npm run compile **classes", - "compileStrategies": "npm run compile **strategies", - "compileIndicators": "npm run compile **indicators", - "rmExpertsEx": "shx --silent rm -r ./Experts/*.ex5 || npm run true", - "rmLibrariesEx": "shx --silent rm -r ./Libraries/*.ex5 || npm run true", - "rmHelpersEx": "shx --silent rm -r ./Helpers/*.ex5 || npm run true", - "rmStrategiesEx": "shx --silent rm -r ./Strategies/*.ex5 || npm run true", - "rmClassesEx": "shx --silent rm -r ./Classes/*.ex5 || npm run true", - "rmIndicatorsEx": "shx --silent rm -r ./Indicators/*.ex5 || npm run true", - "prepareWorkspace": "npm run cleanupEx && npm run compileEA", - "generatePack": "npm run prepareWorkspace && npm run pack && npm run cleanupEx && npm run compileLibraries && npm run compileIndicators" + "mqlHelper": "node mqlHelper.js", + "cleanupEx": "npm run mqlHelper cleanup", + "compileWorkspace": "npm run mqlHelper *", + "compileExperts": "npm run mqlHelper experts", + "compileLibraries": "npm run mqlHelper libraries", + "compileHelpers": "npm run mqlHelper helpers", + "compileClasses": "npm run mqlHelper classes", + "compileIndicators": "npm run mqlHelper indicators", + "repackXCATBEA": "node prepareXCATBEA.js" }, "repository": { "type": "git", diff --git a/prepareXCATBEA.js b/prepareXCATBEA.js new file mode 100644 index 00000000..797e2134 --- /dev/null +++ b/prepareXCATBEA.js @@ -0,0 +1,35 @@ +// +// Import Requirements ... +const XProjectTools = require("./x-mql-project.tools"); + +// +// define constants ... +const projectName = "XCATBEA"; + +// +// Projects Resources ... +const projectResources = [ + "Libraries/*", // Required Libraries + "Classes/*", // Required Classes + "XCATBEA/*", // XCATBEA Projects ... + "Indicators/x-saherelm.x121.xcatb", // Required Indicators + "Helpers/x-saherelm.x121.xcatb.helper", // Indicator's Helpers Classes + "Experts/x-saherelm.x121.xcatb.ea", // Expert Advisers +]; + +// +run(); + +/** + * Main Project Function ... + */ +async function run() { + // + await XProjectTools.prepareProject( + projectName, + projectResources + ); +} + + + diff --git a/x-mql-project.tools.js b/x-mql-project.tools.js new file mode 100644 index 00000000..05d42239 --- /dev/null +++ b/x-mql-project.tools.js @@ -0,0 +1,494 @@ +/** + * XProject Tools Module ... + * a module for handle MQL5 Projects Compile and Packing ... + * + * Maintainer + * + * Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) + */ + +// +// Import Requirements ... +const execSync = require("child_process").execSync; +const XFileTools = require("./Documents/JsModules/x-file.tools"); +const XShellTools = require("./Documents/JsModules/x-shell.tools"); +const XColorTools = require("./Documents/JsModules/x-color.tools"); +const XTypeTools = require("./Documents/JsModules/x-type-detector.tools"); + +// +// Definitions ... +const packsPath = XFileTools.joinPath(".", "Packs"); +const workspacePaths = [ + "Classes", // Required Classes + "Experts", // Expert Advisers + "Helpers", // Indicator's Helpers Classes + "Indicators", // Required Indicators + "Libraries", // Required Libraries + "XCATBEA", // XCATBEA Projects ... +]; + +// +//#region Tools ... + +/** + * Handle Compile and Pack Projects ... + * + * @param {string} projectName + * @param {string[]} resources + * @param {boolean} forceCleanup + * @param {boolean} forceCompileIndicators + */ +async function prepareProject( + projectName = "", + resources = [], + forceCleanup = true, + forceCompileIndicators = true +) { + // + // Check Resources Has Child ... + let isValidArgs = + resources.length > 0 && + XTypeTools.isArray(resources); + if (!isValidArgs) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Invalid Resource List ...", XColorTools.COLOR_NAMES.Red) + ); + } + + // + // Check Project Name is Valid ... + isValidArgs = + projectName.length > 0 && + XTypeTools.isString(projectName); + if (!isValidArgs) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Empty Project Name ...", XColorTools.COLOR_NAMES.Red) + ); + } + + // + // Prepare Pack Folder Exists ... + let isExists = XFileTools.isDirectoryExists(packsPath); + if (!isExists) { + XFileTools.createDirectory(packsPath); + } + + // + // Check Folder Exists or not ... + // if Exists Remove it ... + // Create Project Folder on Packs ... + const prjFolderOnPacks = XFileTools.joinPath(packsPath, projectName); + isExists = XFileTools.isDirectoryExists(prjFolderOnPacks); + if (isExists) { + await XFileTools.removeDirectory(prjFolderOnPacks, true); + } + XFileTools.createDirectory(prjFolderOnPacks); + + // + // Extract Required to Compile Resources List ... + let compileList = await extractResources(resources, true); + if (!compileList || compileList.length == 0) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Resource List Extraction to Compile Failed ...", XColorTools.COLOR_NAMES.Red) + ); + + // + return; + } + + // + // Compile Resources Files ... + for (const f of compileList) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to Compile: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) + ); + + // + await recursiveTriesToCompileFile(f, 0); + } + + // + // Extract Required to Pack Resources List ... + let packList = await extractResources(resources, false); + if (!packList || packList.length == 0) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Resource List Extraction to Pack Failed ...", XColorTools.COLOR_NAMES.Red) + ); + + // + return; + } + + // + // Loop through Files ... + for (const f of packList) { + // + // Prepare Destination Path ... + const fBasePath = XFileTools.basename(f); + let fDestPath = f.replace(fBasePath, ""); + fDestPath = fDestPath.substring(0, fDestPath.length - 1); + fDestPath = XFileTools.joinPath(prjFolderOnPacks, fDestPath); + + // + const isFDestPathExists = XFileTools.isDirectoryExists(fDestPath); + if (!isFDestPathExists) { + XFileTools.createDirectory(fDestPath); + } + + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to copy: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue), + XColorTools.applyForegroundColor(" to : ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(fDestPath, XColorTools.COLOR_NAMES.Magenta) + ); + + // + let result = await XFileTools.copyFile(f, fDestPath); + if (result) { + // + const msg = "copy successfully ..."; + console.log( + XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green) + ); + } else { + // + const msg = "copy failed ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + } + + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Project: ", XColorTools.COLOR_NAMES.Green), + XColorTools.applyForegroundColor(projectName, XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(" Compiled and Packed Successfully ...", XColorTools.COLOR_NAMES.Green), + ); + + // + // Cleanup WorkSpace if Provided ... + if (forceCleanup) { + await cleanupWorkSpace(); + } + + // + // Compile Indicators ... + if (forceCompileIndicators) { + await runCommand("Indicators"); + } +} + +/** + * Extract required Files List ... + * + * @param {boolean} forCompile + * + * @returns Promise + */ +async function extractResources( + resources = [], + forCompile = true +) { + // + let result = []; + + // + // Loop Through Project Resources and Extract Files List to Compile ... + for (const resource of resources) { + // + // Prepare Normalized Resource Path ... + let resourcePath = XFileTools.joinPath(".", resource); + + // + // Handle Wild Card Resources ... + if (resourcePath.endsWith("//*") || + resourcePath.endsWith("\\*")) { + // + resourcePath = resourcePath.substring(0, resourcePath.length - 2); + const files = await XFileTools.extractFiles( + resourcePath, + forCompile ? [".mq5", ".mq4"] : [".ex5", ".ex4"] + ); + + // + result = result.concat(files); + } + // + // Handle Direct File Resources ... + else { + // + // Check MQL 5 Version ... + let fileResourcePath = resourcePath + (forCompile ? ".mq5" : ".ex5"); + + // + // Check File Exists ... + let isExists = XFileTools.isFileExists(fileResourcePath); + if (!isExists) { + // + // Check MQL 4 Version ... + fileResourcePath = resourcePath + (forCompile ? ".mq4" : ".ex4"); + isExists = XFileTools.isFileExists(fileResourcePath); + } + + // + // Add File Path to Files List if Exists ... + if (isExists) { + result.push(fileResourcePath); + } + } + } + + // + return result; +} + +/** + * try to compile a file ... + * @param {string} f + * @param {number} numberOfTries + */ +async function recursiveTriesToCompileFile(f = "", numberOfTries = 0) { + // + let result = await handleFileCompile(f); + if (result) { + // + const msg = "compiled successfully ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green)); + return result; + } else { + // + if (numberOfTries < 10) { + // + numberOfTries++; + + // + const msg = "retry (" + (numberOfTries + 1) + ") ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.LightMagenta)); + await recursiveTriesToCompileFile(f, numberOfTries); + } else { + // + const msg = "failed ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + + // + return false; + } + } +} + +/** + * execute compile task on Specific File ... + * @param {string} f file path to Execute Compile task ... + * @returns + */ +async function handleFileCompile(f = "") { + // + let result = false; + + // + let exResult = await compileMQLFile(f); + if (exResult.includes("0 errors")) { + result = true; + } else { + result = false; + } + + // + return result; +} + +/** + * Compile Specific MQL File ... + * + * @param {string} path MQL file path ... + * @returns + */ +async function compileMQLFile(path = "") { + // + // Check File Exists ... + const isExists = XFileTools.isFileExists(path); + if (!isExists) { + // + const msg = "file not found ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + + // + const ext = XFileTools.getFileExtension(path); + if (ext !== ".mq5" && ext !== "mq4") { + // + const msg = "invalid file extension ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + + // + const cwd = __dirname; + const cmd = "compile.cmd " + path; + + // + const result = await XShellTools.execute(cmd, cwd); + return result; +} + +/** + * Run Specified Command in workspace ... + * + * @param {string} cmd + * @returns + */ +async function runCommand(cmd = "") { + // + // Validate Args ... + let isValidArgs = cmd.length > 0 && + XTypeTools.isString(cmd); + + // + // Validate Commands ... + if (isValidArgs) { + // + // Check Available Commands ... + isValidArgs = + cmd === "*" || + cmd === "cleanup" || + workspacePaths.includes(cmd) || + workspacePaths.map(x => x.toLowerCase(x)).includes(cmd.toLowerCase()); + } + if (!isValidArgs) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Invalid Command ...", XColorTools.COLOR_NAMES.Red) + ); + } + + // + // Compile ... + if (cmd == "*") { + await compileWorkSpace(); + } else if (cmd == "cleanup") { + await cleanupWorkSpace(); + } else { + // + // Select Workspace to Compile ... + const folder = workspacePaths + .find(x => x.toLowerCase() === cmd.toLowerCase()); + isValidArgs = + XTypeTools.isString(folder) && + folder.length > 0; + if (!isValidArgs) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Invalid Command ...", XColorTools.COLOR_NAMES.Red) + ); + } + + // + // Extract Required to Compile Resources List ... + let compileList = await XFileTools.extractFiles( + folder, + [".mq5", ".mq4"] + ); + if (!compileList || compileList.length == 0) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("Extraction to Compile Failed ...", XColorTools.COLOR_NAMES.Red) + ); + + // + return; + } + + // + // Compile Resources Files ... + for (const f of compileList) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to Compile: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) + ); + + // + await recursiveTriesToCompileFile(f, 0); + } + } +} + +/** + * Cleanup Workspace compiled files ... + */ +async function cleanupWorkSpace() { + // + for (const path of workspacePaths) { + // + const fSourcePath = XFileTools.joinPath(".", path); + const filesToRemove = await XFileTools.extractFiles(fSourcePath, [".ex5", ".ex4"]); + for (const f of filesToRemove) { + // + // Log ... + console.log( + XColorTools.applyForegroundColor("try to Remove: ", XColorTools.COLOR_NAMES.Yellow), + XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue) + ); + + // + let result = await XFileTools.removeFile(f); + if (result) { + // + const msg = "removed successfully ..."; + console.log( + XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green) + ); + } else { + // + const msg = "removed failed ..."; + console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red)); + throw msg; + } + } + } +} + +/** + * Compile Workspace ... + */ +async function compileWorkSpace() { + // + for (const path of workspacePaths) { + await runCommand(path); + } +} +//#endregion + +// +//#region Module Exports ... +module.exports = { + extractResources, + recursiveTriesToCompileFile, + handleFileCompile, + compileMQLFile, + runCommand, + cleanupWorkSpace, + compileWorkSpace, + prepareProject +} +//#endregion \ No newline at end of file