cleanup all js Helper apps and Create an MQL Module Helper and do all requirements inside it ...
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* XMQL Helper CLI Tools ...
|
||||||
|
* a module for handle MQL5 Commands running ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (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);
|
||||||
@@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,494 @@
|
|||||||
|
/**
|
||||||
|
* XProject Tools Module ...
|
||||||
|
* a module for handle MQL5 Projects Compile and Packing ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (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<string[]>
|
||||||
|
*/
|
||||||
|
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
|
||||||
+2
-1
@@ -7,7 +7,8 @@
|
|||||||
"settings": {
|
"settings": {
|
||||||
"C_Cpp.default.includePath": [
|
"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\\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}",
|
"C_Cpp.clang_format_style": "{ BasedOnStyle: Microsoft, UseTab: Never, IndentWidth: 4, TabWidth: 4, ColumnLimit: 0}",
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
@echo off
|
@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"
|
set "LOGFILE=%~dpn1.log"
|
||||||
|
|
||||||
if "%~1"=="" (
|
if "%~1"=="" (
|
||||||
|
|||||||
-443
@@ -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;
|
|
||||||
}
|
|
||||||
-127
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* XMQL Helper CLI Tools ...
|
||||||
|
* a module for handle MQL5 Commands running ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (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);
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+9
-18
@@ -8,24 +8,15 @@
|
|||||||
"aaa": "|----------|",
|
"aaa": "|----------|",
|
||||||
"aab": "| Commons |",
|
"aab": "| Commons |",
|
||||||
"aac": "|----------|",
|
"aac": "|----------|",
|
||||||
"compile": "node compile.js",
|
"mqlHelper": "node mqlHelper.js",
|
||||||
"pack": "node pack.js",
|
"cleanupEx": "npm run mqlHelper cleanup",
|
||||||
"cleanupEx": "node cleanupEx.js",
|
"compileWorkspace": "npm run mqlHelper *",
|
||||||
"compileEA": "node compileEA.js",
|
"compileExperts": "npm run mqlHelper experts",
|
||||||
"compileExperts": "npm run compile **experts",
|
"compileLibraries": "npm run mqlHelper libraries",
|
||||||
"compileLibraries": "npm run compile **libraries",
|
"compileHelpers": "npm run mqlHelper helpers",
|
||||||
"compileHelpers": "npm run compile **helpers",
|
"compileClasses": "npm run mqlHelper classes",
|
||||||
"compileClasses": "npm run compile **classes",
|
"compileIndicators": "npm run mqlHelper indicators",
|
||||||
"compileStrategies": "npm run compile **strategies",
|
"repackXCATBEA": "node prepareXCATBEA.js"
|
||||||
"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"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,494 @@
|
|||||||
|
/**
|
||||||
|
* XProject Tools Module ...
|
||||||
|
* a module for handle MQL5 Projects Compile and Packing ...
|
||||||
|
*
|
||||||
|
* Maintainer
|
||||||
|
*
|
||||||
|
* Hadi Khazaee Asl <https://saherelm.ir> (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<string[]>
|
||||||
|
*/
|
||||||
|
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
|
||||||
Reference in New Issue
Block a user