/*jshint laxbreak: true*/
/*jslint node: true, for: true*/
(function biddle() {
"use strict";
var node = {
child : require("child_process").exec,
crypto: require("crypto"),
fs : require("fs"),
http : require("http"),
https : require("https"),
path : require("path")
},
text = {
blue : "\u001b[34m",
bold : "\u001b[1m",
cyan : "\u001b[36m",
green : "\u001b[32m",
nocolor : "\u001b[39m",
none : "\u001b[39m\u001b[0m",
normal : "\u001b[0m",
purple : "\u001b[35m",
red : "\u001b[31m",
underline: "\u001b[4m",
yellow : "\u001b[33m"
},
commands = { // The list of supported biddle commands.
commands : "List the supported commands to the console.",
copy : "Copy files or directory trees from one location to another on the local file s" +
"ystem.",
get : "Get something via http/https.",
global : "Make an installed application into a global command in the terminal.",
hash : "Generate a hash sequence against a file.",
help : "Parse biddle's readme.md to the terminal.",
install : "Install a published application.",
list : "List installed and/or published applications.",
markdown : "Parse any markdown and output to terminal.",
publish : "Publish an application/version.",
remove : "Remove a file or directory from the local file system.",
status : "Determine if version on installed applications are behind the latest published" +
" version.",
test : "Test automation.",
uninstall: "Uninstall an application installed by biddle.",
unpublish: "Unpublish an application, or a version, published by biddle.",
unzip : "Unzip a zip file.",
update : "Issues a status command and automatically installs the latest version if the i" +
"nstalled version is outdated.",
version : "Output an installed application's version number.",
zip : "Zip a file or directory."
},
data = {
abspath : "", // Local absolute path to biddle.
address : {
applications: "", // Local absolute path where applications will be installed to.
downloads : "", // Local absolute path to biddle download directory.
publications: "", // Local absolute path where applications will be published to.
target : "" // Location where files will be written to.
},
applications : "applications", // default place to store installed applications
childtest : false, // If the current biddle instance is a child of another biddle instance (occurs due to test automation)
command : "", // Executed biddle command.
cwd : process.cwd(), // Current working directory before running biddle.
filename : "", // Stores an inferred file name when files need to be written and a package.json is not used, such as the get command.
hashFile : "", // Stores hash value from reading a downloaded hash file. Used for hash comparison with the install command.
hashZip : "", // Stores locally computed hash value for a downloaded zip file. Used for hash comparison with the install command.
ignore : [], // List of relative locations to ignore from the .biddlerc file's exclusions object.
input : [], // Normalized process.argv list.
installed : {}, // Parsed data of the installed.json file. Data about applications installed with biddle.
internal : false, // Used for biddle's internal enhancements
latestVersion: false, // Used in the publish command to determine if the application is the latest version
packjson : {}, // Parsed data of a directory's package.json file. Used with the publish command.
parallel : false, // Whether variants should be published in parallel (faster but not stable) or in sequence. Set from .biddlerc
platform : "", // Lowercase of Node's process.platform
protocoltest : (/^(((ht)|f)tps?:\/\/)/i), // To determine if input requires use of HTTP get
publications : "publications", // default location to store published applications
published : {}, // Parsed data of the published.json file. Data about applications published by biddle.
sudo : false // If biddle is executed with administrative rights in POSIX.
},
cmds = { // The OS specific commands executed outside Node.js
pathRead : function biddle_cmds_pathRead() { // Used in command global to read the OS's stored paths
return "powershell.exe -nologo -noprofile -command \"[Environment]::GetEnvironmentVari" +
"able('PATH','Machine');\"";
},
pathRemove: function biddle_cmds_pathRemove(cmdFile) { // Used in command global to remove the biddle path from the Windows path list
return "powershell.exe -nologo -noprofile -command \"$PATH='" + cmdFile + "';[E" +
"nvironment]::SetEnvironmentVariable('PATH',$PATH,'Machine');\"";
},
pathSet : function biddle_cmds_pathSet(appspath) { // Used in command global to add the biddle path to the Windows path list
return "powershell.exe -nologo -noprofile -command \"$PATH=[Environment]::GetEnvironme" +
"ntVariable('PATH');[Environment]::SetEnvironmentVariable('PATH',$PATH + ';" +
appspath + "cmd','Machine');\"";
},
unzip : function biddle_cmds_unzip(filename, outputDirectory) { // Unzips a zip archive into a collection
if (data.platform === "win32") {
return "powershell.exe -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compre" +
"ssion.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('" +
filename + "', '" + outputDirectory + "'); }\"";
}
return "unzip -oq " + filename + " -d " + outputDirectory;
},
zip : function biddle_cmds_zip(filename, file) { // Stores all items of the given directory into a zip archive directly without creating a new directory. Locations resolved by a symlink are stored, but the actual symlink is not stored.
if (data.platform === "win32") {
return "powershell.exe -nologo -noprofile -command \"& { Add-Type -A 'System.IO.Compre" +
"ssion.FileSystem'; [IO.Compression.ZipFile]::CreateFromDirectory('.', '" +
filename + "'); }\"";
}
if (file === "") {
return "zip -r9yq " + filename + " ." + node.path.sep + " *.[!.]";
}
return "zip -r9yq " + filename + " " + file;
}
},
apps = {};
apps.commands = function biddle_commands() {
var keys = Object.keys(commands),
len = keys.length,
comm = "",
lens = 0,
a = 0,
b = 0;
console.log(text.underline + "biddle Commands" + text.normal);
console.log("");
do {
if (keys[a].length > lens) {
lens = keys[a].length;
}
a = a + 1;
} while (a < len);
a = 0;
do {
comm = keys[a];
b = comm.length;
if (b < lens) {
do {
comm = comm + " ";
b = b + 1;
} while (b < lens);
}
console.log(text.cyan + comm + text.nocolor + ": " + commands[keys[a]]);
a = a + 1;
} while (a < len);
};
apps.commas = function biddle_commas(number) {
var str = String(number),
arr = [],
a = str.length;
if (a < 4) {
return str;
}
arr = String(number).split("");
a = arr.length;
do {
a = a - 3;
arr[a] = "," + arr[a];
} while (a > 3);
return arr.join("");
};
apps.copy = function biddle_copy(target, destination, exclusions, callback) {
var numb = {
dirs : 0,
files: 0,
link : 0,
size : 0
},
start = "",
dest = "",
exlen = exclusions.length,
dirs = {},
util = {};
util.complete = function biddle_copy_complete(item) {
var out = ["biddle copied "];
delete dirs[item];
if (Object.keys(dirs).length < 1) {
if (data.command === "copy") {
out.push(text.green);
out.push(text.bold);
out.push(numb.dirs);
out.push(text.none);
out.push(" director");
if (numb.dirs === 1) {
out.push("y, ");
} else {
out.push("ies, ");
}
out.push(text.green);
out.push(text.bold);
out.push(numb.files);
out.push(text.none);
out.push(" file");
if (numb.files !== 1) {
out.push("s");
}
out.push(", and ");
out.push(text.green);
out.push(text.bold);
out.push(numb.link);
out.push(text.none);
out.push(" symbolic link");
if (numb.link !== 1) {
out.push("s");
}
out.push(" at ");
out.push(text.green);
out.push(text.bold);
out.push(apps.commas(numb.size));
out.push(text.none);
out.push(" bytes.");
console.log(out.join(""));
console.log(
"Copied " + text.cyan + target + text.nocolor + " to " + text.green +
destination + text.nocolor
);
}
callback();
}
};
util.eout = function biddle_copy_eout(er, name) {
var filename = target.split(node.path.sep);
apps.remove(
destination + node.path.sep + filename[filename.length - 1],
function biddle_copy_eout_remove() {
apps.errout({error: er, name: name});
}
);
};
util.dir = function biddle_copy_dir(item) {
node
.fs
.readdir(item, function biddle_copy_dir_makedir_readdir(er, files) {
var place = (data.command === "publish")
? (item === start)
? dest
: dest + item.replace(start + node.path.sep, "")
: dest + item.replace(data.cwd.toLowerCase() + node.path.sep, "");
if (er !== null) {
return util.eout(er, "biddle_copy_dir_readdir");
}
apps.makedir(place, function biddle_copy_dir_makedir() {
var a = files.length,
b = 0;
if (a > 0) {
delete dirs[item];
do {
dirs[item + node.path.sep + files[b]] = true;
b = b + 1;
} while (b < a);
b = 0;
do {
util.stat(item + node.path.sep + files[b], item);
b = b + 1;
} while (b < a);
} else {
util.complete(item);
}
});
});
};
util.file = function biddle_copy_file(item, dir, prop) {
var place = (data.command === "publish")
? dest + item.replace(start + node.path.sep, "")
: dest + item.replace(data.cwd.toLowerCase() + node.path.sep, ""),
readStream = node
.fs
.createReadStream(item),
writeStream = {},
errorflag = false;
if (item === dir) {
place = dest + item
.split(node.path.sep)
.pop();
}
writeStream = node
.fs
.createWriteStream(place, {mode: prop.mode});
readStream.on("error", function biddle_copy_file_readError(error) {
errorflag = true;
return util.eout(error, "biddle_copy_file_readError");
});
writeStream.on("error", function biddle_copy_file_writeError(error) {
errorflag = true;
return util.eout(error, "biddle_copy_file_writeError");
});
if (errorflag === true) {
return;
}
writeStream.on("open", function biddle_copy_file_write() {
readStream.pipe(writeStream);
});
writeStream.once("finish", function biddle_copy_file_finish() {
var filename = item.split(node.path.sep);
node
.fs
.utimes(
dest + node.path.sep + filename[filename.length - 1],
prop.atime,
prop.mtime,
function biddle_copy_file_finish_utimes() {
util.complete(item);
}
);
});
};
util.link = function biddle_copy_link(item, dir) {
node
.fs
.readlink(item, function biddle_copy_link_readlink(err, resolvedlink) {
if (err !== null) {
return util.eout(err, "biddle_copy_link_readlink");
}
resolvedlink = apps.relToAbs(resolvedlink, data.cwd);
node
.fs
.stat(resolvedlink, function biddle_copy_link_readlink_stat(ers, stats) {
var type = "file",
place = dest + item;
if (ers !== null) {
return util.eout(ers, "biddle_copy_link_readlink_stat");
}
if (stats === undefined || stats.isFile === undefined) {
return util.eout(
"Error in performing stat against " + item,
"biddle_copy_link_readlink_stat"
);
}
if (item === dir) {
place = dest + item
.split(node.path.sep)
.pop();
}
if (stats.isDirectory() === true) {
type = "junction";
}
node
.fs
.symlink(
resolvedlink,
place,
type,
function biddle_copy_link_readlink_stat_makelink(erl) {
if (erl !== null) {
return util.eout(erl, "biddle_copy_link_readlink_stat_makelink");
}
util.complete(item);
}
);
});
});
};
util.stat = function biddle_copy_stat(item, dir) {
var a = 0,
func = (data.command === "copy")
? "lstat"
: "stat";
if (exlen > 0) {
do {
if (item.replace(start + node.path.sep, "") === exclusions[a]) {
exclusions.splice(a, 1);
exlen = exlen - 1;
util.complete(item);
return;
}
a = a + 1;
} while (a < exlen);
}
node.fs[func](item, function biddle_copy_stat_callback(er, stats) {
if (er !== null) {
return util.eout(er, "biddle_copy_stat_callback");
}
if (stats === undefined || stats.isFile === undefined) {
return util.eout("stats object is undefined", "biddle_copy_stat_callback");
}
if (stats.isFile() === true) {
numb.files = numb.files + 1;
numb.size = numb.size + stats.size;
if (item === dir) {
apps.makedir(dest, function biddle_copy_stat_callback_file() {
util.file(item, dir, {
atime: (Date.parse(stats.atime) / 1000),
mode : stats.mode,
mtime: (Date.parse(stats.mtime) / 1000)
});
});
} else {
util.file(item, dir, {
atime: (Date.parse(stats.atime) / 1000),
mode : stats.mode,
mtime: (Date.parse(stats.mtime) / 1000)
});
}
} else if (stats.isDirectory() === true) {
numb.dirs = numb.dirs + 1;
util.dir(item);
} else if (stats.isSymbolicLink() === true) {
numb.link = numb.link + 1;
if (item === dir) {
apps.makedir(dest, function biddle_copy_stat_callback_symb() {
util.link(item, dir);
});
} else {
util.link(item, dir);
}
} else {
util.complete(item);
}
});
};
target = target.replace(/(\\|\/)/g, node.path.sep);
destination = destination.replace(/(\\|\/)/g, node.path.sep);
dest = apps.relToAbs(destination, data.cwd) + node.path.sep;
start = apps.relToAbs(target, data.cwd);
util.stat(start, start);
};
apps.errout = function biddle_errout(errData) {
var error = (
typeof errData.error !== "string" || errData.error.toString().indexOf("Error: ") === 0
)
? errData
.error
.toString()
.replace("Error: ", text.bold + text.red + "Error:" + text.none + " ")
: text.bold + text.red + "Error:" + text.none + " " + errData
.error
.toString(),
stack = new Error().stack;
if (data.platform === "win32") {
stack = stack.replace("Error", "Stack trace\r\n-----------");
} else {
stack = stack.replace("Error", "Stack trace\n-----------");
}
error = error
.toString()
.replace(/(\s+)$/, "");
if (data.command === "test" && (data.input[2] === "biddle" || data.input[2] === "biddletesta" || data.input[2] === "biddletestb")) {
apps.remove(data.abspath + "unittest", function biddle_errout_dataClean() {
apps.remove(
data.abspath + "temp",
function biddle_errout_dataClean_tempTestClean() {
console.log(text.red + "Unit test failure." + text.nocolor);
if (errData.stdout !== undefined) {
console.log(errData.stdout);
}
console.log(
text.bold + text.cyan + "Function:" + text.none + " " + errData.name
);
console.log(error);
console.log("");
console.log(stack);
if (errData.time === undefined) {
console.log(text.none);
} else {
console.log("");
console.log(errData.time + text.none);
}
if (errData.name.indexOf("biddle_test") === 0) {
data.published.biddletesta = {
directory: data.abspath + "publications" + node.path.sep + "biddletesta"
};
data.installed.biddletesta = {
location: data.abspath + "applications" + node.path.sep + "biddletesta"
};
data.input[2] = "biddletesta";
data.input[3] = "all";
setTimeout(function biddle_errout_delayPrimary() {
apps.uninstall(true);
apps.unpublish(true);
setTimeout(function biddle_errout_delaySecondary() {
process.exit(1);
}, 500);
}, 1000);
}
}
);
});
} else {
apps.remove(
data.abspath + "temp",
function biddle_errout_dataClean_tempNontestClean() {
console.log(
text.bold + text.cyan + "Function:" + text.none + " " + errData.name
);
console.log(error);
if (data.childtest === false) {
console.log("");
console.log(stack);
console.log("");
console.log(
"Please report defects to https://github.com/prettydiff/biddle/issues" + text.none
);
}
process.exit(1);
}
);
}
};
apps.get = function biddle_get(url, fileName, callback) {
var a = (typeof url === "string")
? url.indexOf("s://")
: 0,
zippy = ((data.command === "install" || data.command === "update") && (/(\.zip)$/).test(url) === true),
addy = (zippy === true)
? data.address.downloads
: data.address.target,
getcall = function biddle_get_getcall(res) {
var file = [];
res.on("data", function biddle_get_getcall_data(chunk) {
file.push(chunk);
});
res.on("end", function biddle_get_getcall_end() {
if (res.statusCode !== 200) {
if ((res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 303 || res.statusCode === 307 || res.statusCode === 308) && res.headers.location !== undefined) {
console.log(
res.statusCode + " " + node.http.STATUS_CODES[res.statusCode] +
", for request " + url
);
url = res.headers.location;
biddle_get(url, fileName, callback);
} else if (data.command !== "install" && data.command !== "update") {
console.log(
res.statusCode + " " + text.bold + text.red + node.http.STATUS_CODES[res.statusCode] +
text.none + ", for request " + url
);
} else {
return apps.errout({
error: data.command + " failed due to " + res.statusCode + " " + text.bold + text.red +
node
.http
.STATUS_CODES[res.statusCode] + text.none + " on request " + url,
name : "biddle_get_getcall_end"
});
}
} else if ((data.command !== "install" && data.command !== "update" && (/[\u0002-\u0008]|[\u000e-\u001f]/).test(file[0]) === true) || zippy === true) {
apps.makedir(addy, function biddle_get_getcall_end_complete() {
apps.writeFile(
Buffer.concat(file),
addy + fileName,
function biddle_get_getcall_end_complete_writeFile(filedata) {
callback(filedata, url);
}
);
});
} else {
callback(file.join(""), url);
}
});
res.on("error", function biddle_get_getcall_error(error) {
return apps.errout({error: error, name: "biddle_get_getcall_error"});
});
};
if (data.protocoltest.test(url) === false) {
if ((/(\.zip)$/).test(url) === true) {
if (data.command !== "update") {
console.log(
"Address " + url + " is missing the " + text.cyan + "http(s)" + text.nocolor +
" scheme, treating as a local path..."
);
}
apps.makedir(addy, function biddle_get_localZip() {
apps.copy(apps.relToAbs(url, data.cwd), data.abspath + "downloads", [], callback);
});
} else {
apps.readBinary(url, function biddle_get_readLocal(filedata) {
callback(filedata, url);
});
}
} else if (a > 0 && a < 10) {
node
.https
.get(url, getcall);
} else {
node
.http
.get(url, getcall);
}
};
apps.getFileName = function biddle_getFileName(filepath) {
var paths = [],
output = "";
if (filepath === undefined) {
return "download.xxx";
}
if (data.protocoltest.test(filepath) === true) {
output = filepath.replace(data.protocoltest, "");
if (output.indexOf("?") > 0) {
output = output.slice(0, output.indexOf("?"));
}
paths = output.split("/");
} else {
paths = filepath
.replace(/^(\/|\\)+/, "")
.split(node.path.sep);
}
if (paths[paths.length - 1].length > 0) {
output = paths[paths.length - 1].toLowerCase();
} else {
do {
paths.pop();
} while (paths.length > 0 && paths[paths.length - 1] === "");
if (paths.length < 1) {
return "download.xxx";
}
output = paths[paths.length - 1].toLowerCase();
}
return apps.sanitizef(output);
};
apps.getpjson = function biddle_getpjson(file, callback) {
node
.fs
.readFile(file, "utf8", function biddle_getpjson_readfile(err, fileData) {
if (err !== null && err !== undefined) {
if (err.toString().indexOf("no such file or directory") > 0) {
file = file.replace(node.path.sep + "package.json", "");
node
.fs
.stat(file, function biddle_getpjson_readfile_testdir(errs) {
if (errs !== null && errs.toString().indexOf("no such file or directory") > -1) {
apps.errout({
error: "Directory " + text.red + text.bold + file + text.none + " does not exist.",
name : "biddle_getpjson_readfile_testdir"
});
} else {
apps.errout({
error: "The package.json file is missing from " + data.input[2] + ". biddle cannot pub" +
"lish without a package.json file. Perhaps " + apps.relToAbs(
data.input[2],
data.cwd
) + " is the incorrect location.",
name : "biddle_getpjson_readFile_testdir"
});
}
});
} else {
apps.errout({error: err, name: "biddle_getpjson_readFile"});
}
return;
}
data.packjson = JSON.parse(fileData);
if (typeof data.packjson.name !== "string" || data.packjson.name.length < 1) {
return apps.errout({
error: "The package.json file is missing the required " + text.red + "name" + text.nocolor +
" property.",
name : "biddle_getpjson_readfile"
});
}
if (typeof data.packjson.version !== "string" || data.packjson.version.length < 1) {
return apps.errout({
error: "The package.json file is missing the required " + text.red + "version" +
text.nocolor + " property.",
name : "biddle_getpjson_readfile"
});
}
if (typeof data.packjson.name !== "string") {
if (typeof data.packjson.name === "object" && data.packjson.name !== null) {
data.packjson.name = JSON.stringify(data.packjson.name);
} else {
data.packjson.name = String(data.packjson.name);
}
}
if (typeof data.packjson.version !== "string") {
if (typeof data.packjson.version === "object" && data.packjson.version !== null) {
data.packjson.version = JSON.stringify(data.packjson.version);
} else {
data.packjson.version = String(data.packjson.version);
}
}
data.packjson.name = apps.sanitizef(data.packjson.name);
callback();
});
};
apps.global = function biddle_global(loc) {
var bin = loc + "bin";
if (data.input[2] === undefined || data.input[2] === "") {
data.input[2] = "biddle";
} else if (data.input[2] === "remove") {
data.input[2] = "biddle";
data.input[3] = "remove";
} else {
if (data.installed[data.input[2]] === undefined && data.command === "global") {
return apps.errout({
error: "Application " + data.input[2] + " is not installed by biddle. biddle will only" +
" add applications to the environmental path that it has installed.",
name : "biddle_global"
});
}
bin = loc + "bin";
}
if (data.platform === "win32") {
return node.child(
cmds.pathRead(),
function biddle_global_winRead(er, stdout, stder) {
var remove = "";
if (er !== null) {
return apps.errout({error: er, name: "biddle_global_winRead"});
}
if (stder !== null && stder !== "") {
return apps.errout({error: stder, name: "biddle_global_winRead"});
}
if (stdout.indexOf(bin) > -1) {
if (data.input[3] === "remove") {
remove = stdout
.replace(";" + loc + "cmd", "")
.replace(/(\s+)$/, "");
return node.child(
cmds.pathRemove(remove),
function biddle_global_winRead_winRemovePath(erw, stdoutw, stderw) {
if (erw !== null) {
return apps.errout({error: erw, name: "biddle_global_winRead_winRemovePath"});
}
if (stderw !== null && stderw !== "") {
return apps.errout(
{error: stderw, name: "biddle_global_winRead_winRemovePath"}
);
}
if (data.command === "global") {
console.log(loc + "cmd removed from %PATH%.");
}
return stdoutw;
}
);
}
if (data.command === "global") {
return apps.errout({
error: loc + "cmd is already in %PATH%",
name : "biddle_global_winRead"
});
}
}
if (data.input[3] === "remove" && data.command === "global") {
return apps.errout({
error: loc + "cmd is not present in %PATH%",
name : "biddle_global_winRead"
});
}
node.child(
cmds.pathSet(loc),
function biddle_global_winRead_winWritePath(erw, stdoutw, stderw) {
if (erw !== null) {
return apps.errout({error: erw, name: "biddle_global_winRead_winWritePath"});
}
if (stderw !== null && stderw !== "") {
return apps.errout({error: stderw, name: "biddle_global_winRead_winWritePath"});
}
if (data.command === "global") {
console.log(loc + "cmd added to %PATH%.");
}
return stdoutw;
}
);
}
);
}
node.child("echo ~", function biddle_global_findHome(erh, stdouth, stderh) {
var flag = {
bash_profile: false,
profile : false
},
terminal = function biddle_global_findHome_terminal() {
if (data.input[3] === "remove" && data.command === "global") {
return console.log(
bin + " removed from $PATH but will remain available until the terminal is rest" +
"arted."
);
}
if (data.command === "global") {
console.log(
"Restart the terminal or execute: export PATH=" + bin + ":$PATH"
);
}
},
readPath = function biddle_global_findHome_readPath(dotfile) {
node
.fs
.readFile(
dotfile,
"utf8",
function biddle_global_findHome_readPath_nixRead(err, filedata) {
var pathStatement = "\nexport PATH=\"" + bin + ":$PATH\"\n";
if (err !== null && err !== undefined) {
return apps.errout(
{error: err, name: "biddle_global_findHome_nixStat_nixRead"}
);
}
if (filedata.indexOf(bin) > -1) {
if (data.input[3] === "remove") {
return apps.writeFile(
filedata.replace(pathStatement, ""),
dotfile,
function biddle_global_findHome_readPath_nixRead_nixRemove() {
if (data.command === "global") {
console.log("Path updated in " + dotfile);
}
if (dotfile.indexOf("bash_profile") > 0) {
flag.bash_profile = true;
if (flag.profile === true) {
terminal();
}
} else {
flag.profile = true;
if (flag.bash_profile === true) {
terminal();
}
}
}
);
}
if (data.command === "global") {
return apps.errout({
error: bin + " is already in $PATH",
name : "biddle_global_findHome_readPath_nixRead"
});
}
}
if (data.input[3] === "remove" && data.command !== "uninstall") {
return apps.errout({
error: bin + " is not present in $PATH",
name : "biddle_global_findHome_readPath_nixRead"
});
}
apps.writeFile(
filedata + pathStatement,
dotfile,
function biddle_global_findHome_readPath_nixRead_nixRemove() {
if (data.command === "global") {
console.log("Path updated in " + dotfile);
}
if (dotfile.indexOf("bash_profile") > 0) {
flag.bash_profile = true;
if (flag.profile === true) {
terminal();
}
} else {
flag.profile = true;
if (flag.bash_profile === true) {
terminal();
}
}
}
);
}
);
};
if (erh !== null) {
return apps.errout({error: erh, name: "biddle_global_findHome"});
}
if (stderh !== null && stderh !== "") {
return apps.errout({error: stderh, name: "biddle_global_findHome"});
}
stdouth = stdouth.replace(/\s+/g, "") + "/.";
node
.fs
.stat(
stdouth + "profile",
function biddle_cmds_global_findHome_nixStatProfile(er) {
if (er !== null) {
if (er.toString().indexOf("no such file or directory") > 1) {
flag.profile = true;
if (flag.bash_profile === true) {
terminal();
}
} else {
return apps.errout(
{error: er, name: "biddle_cmds_global_findHome_nixStatProfile"}
);
}
} else {
readPath(stdouth + "profile");
}
}
);
node
.fs
.stat(
stdouth + "bash_profile",
function biddle_cmds_global_findHome_nixStatBash(er) {
if (er !== null) {
if (er.toString().indexOf("no such file or directory") > 1) {
flag.bash_profile = true;
if (flag.profile === true) {
terminal();
}
} else {
return apps.errout(
{error: er, name: "biddle_cmds_global_findHome_nixStatBash"}
);
}
} else {
readPath(stdouth + "bash_profile");
}
}
);
});
};
apps.hash = function biddle_hash(filepath, store, callback) {
var hash = node
.crypto
.createHash("sha512");
if (filepath === "string" && data.input[3] !== undefined) {
hash.update(data.input[3]);
console.log(hash.digest("hex"));
} else {
node
.fs
.stat(filepath, function biddle_hash_stat(er, stat) {
if (er !== null) {
if (er.toString().indexOf("no such file or directory") > 0) {
if (data.command === "install") {
return apps.errout({
error: filepath + " " + text.red + "does not appear to be a zip file" + text.nocolor +
". Install command expects to receive a zip file and a hash file at the same lo" +
"cation and file name.",
name : "biddle_hash_stat"
});
}
return apps.errout({
error: "filepath " + filepath + " is not a file.",
name : "biddle_hash_stat"
});
}
return apps.errout({error: er, name: "biddle_hash_stat"});
}
if (stat === undefined || stat.isFile() === false) {
if (data.command === "install") {
return apps.errout({
error: filepath + " " + text.red + "does not appear to be a zip file" + text.nocolor +
". Install command expects to receive a zip file and a hash file at the same lo" +
"cation and file name.",
name : "biddle_hash_stat"
});
}
return apps.errout({
error: "filepath " + filepath + " is not a file.",
name : "biddle_hash_stat"
});
}
node
.fs
.open(filepath, "r", function biddle_hash_stat_open(ero, fd) {
var msize = (stat.size < 100)
? stat.size
: 100,
buff = new Buffer(msize);
if (ero !== null) {
return apps.errout({error: ero, name: "biddle_hash_stat_open"});
}
node
.fs
.read(
fd,
buff,
0,
msize,
1,
function biddle_hash_stat_open_read(erra, bytesa, buffera) {
var bstring = "",
hashExec = function biddle_hash_stat_open_read_hashExec(filedump) {
hash.on("readable", function biddle_hash_stat_open_read_readBinary_hash() {
var hashdata = hash.read(),
hashstr = "";
if (hashdata !== null) {
hashstr = hashdata
.toString("hex")
.replace(/\s+/g, "");
data[store] = hashstr;
callback(hashstr);
}
});
hash.write(filedump);
hash.end();
};
if (erra !== null) {
return apps.errout({error: erra, name: "biddle_hash_stat_open_read"});
}
bstring = buffera.toString("utf8", 0, buffera.length);
bstring = bstring.slice(2, bstring.length - 2);
if ((/[\u0002-\u0008]|[\u000e-\u001f]/).test(bstring) === true) {
buff = new Buffer(stat.size);
node
.fs
.read(
fd,
buff,
0,
stat.size,
0,
function biddle_hash_stat_open_read_readBinary(errb, bytesb, bufferb) {
if (errb !== null) {
return apps.errout(
{error: errb, name: "biddle_hash_stat_open_read_readBinary"}
);
}
if (bytesb > 0) {
hashExec(bufferb);
}
}
);
} else {
node
.fs
.readFile(filepath, {
encoding: "utf8"
}, function biddle_hash_stat_open_read_readFile(errc, dump) {
if (errc !== null && errc !== undefined) {
return apps.errout({error: errc, name: "biddle_hash_stat_open_read_readFile"});
}
hashExec(dump);
});
}
return bytesa;
}
);
});
});
}
};
apps.install = function biddle_install(zippath, callback) {
var flag = {
hash: false,
late: false,
zip : false
},
hashFile = "",
fileName = "",
dirs = [],
late = (function biddle_install_late() {
var sep = (data.protocoltest.test(zippath) === true)
? "/"
: node.path.sep;
dirs = zippath.split(sep);
fileName = dirs.pop();
return dirs.join(sep) + sep + "latest.txt";
}()),
compareHash = function biddle_install_compareHash() {
apps.hash(
data.address.downloads + fileName,
"hashZip",
function biddle_install_compareHash_hash(hashZip) {
if (hashFile === hashZip) {
var location = "",
puba = [],
pubs = "";
if (data.protocoltest.test(zippath) === true) {
location = zippath
.split("/")
.pop();
puba = zippath.split("/");
puba.pop();
pubs = puba.join("/");
} else {
location = apps.relToAbs(zippath, data.cwd);
pubs = apps.relToAbs(
zippath.slice(0, zippath.lastIndexOf(node.path.sep) + 1),
data.cwd
);
}
apps.zip(function biddle_install_callback() {
node
.fs
.readFile(
data.address.target + "package.json",
function biddle_zip_childfunc_child_install(erf, filedata) {
var status = {
packjson: false,
remove : false
},
packjson = {},
variant = "";
if (erf !== null && erf !== undefined) {
return apps.errout({error: erf, name: "biddle_zip_childfunc_child_install"});
}
packjson = JSON.parse(filedata);
data.packjson = packjson;
variant = (function biddle_zip_childfunc_child_install_variant() {
var name = fileName.replace(packjson.name + "_", ""),
ver = apps.sanitizef(packjson.version);
if (name === "latest.zip" || name === ver + ".zip") {
return "";
}
if (name.indexOf("_latest.zip") === name.length - 11) {
name = name.slice(0, name.length - 11);
} else {
ver = "_" + ver + ".zip";
name = name.slice(0, name.length - ver.length);
}
return name;
}());
if (data.internal === true) {
// internal applications are used only to enhance biddle.
if (data.installed.internal === undefined) {
data.installed.internal = {};
}
data
.installed
.internal[packjson.name] = {};
data
.installed
.internal[packjson.name]
.location = data.address.target;
data
.installed
.internal[packjson.name]
.published = pubs;
if (packjson.test === undefined) {
data
.installed
.internal[packjson.name]
.test = "";
} else {
data
.installed
.internal[packjson.name]
.test = packjson.test;
}
data
.installed
.internal[packjson.name]
.variant = variant;
data
.installed
.internal[packjson.name]
.version = packjson.version;
} else {
data.installed[packjson.name] = {};
data
.installed[packjson.name]
.location = data.address.target;
data
.installed[packjson.name]
.published = pubs;
if (packjson.test === undefined) {
data
.installed[packjson.name]
.test = "";
} else {
data
.installed[packjson.name]
.test = packjson.test;
}
data
.installed[packjson.name]
.variant = variant;
data
.installed[packjson.name]
.version = packjson.version;
}
apps.writeFile(
JSON.stringify(data.installed),
data.abspath + "installed.json",
function biddle_install_compareHash_hash_installedJSON() {
status.packjson = true;
if (status.remove === true) {
callback(packjson);
}
}
);
apps.remove(
data.abspath + "downloads" + node.path.sep + fileName,
function biddle_install_compareHash_hash_remove() {
status.remove = true;
if (status.packjson === true) {
callback(packjson);
}
}
);
}
);
}, {
fileName: fileName,
location: location,
name : ""
});
} else {
return apps.errout({
error: text.red + "Hashes don't match" + text.nocolor + " for " + zippath + ". File is" +
" saved in the downloads directory and will not be installed.\r\nGenerated hash" +
" - " + data.hashZip + "\r\nRequested hash - " + data.hashFile,
name : "biddle_install_compareHash"
});
}
}
);
};
apps.get(zippath, fileName, function biddle_install_getzip() {
flag.zip = true;
if (flag.hash === true && flag.late === true) {
compareHash();
}
});
apps.get(
zippath.replace(".zip", ".hash"),
fileName,
function biddle_install_gethash(fileData) {
flag.hash = true;
hashFile = fileData;
if (flag.zip === true && flag.late === true) {
compareHash();
}
}
);
apps.get(late, fileName, function biddle_install_getlate(fileData) {
var name = "";
if (dirs[dirs.length - 1] === "") {
dirs.pop();
}
name = dirs[dirs.length - 1];
if (typeof data.installed[name] === "object" && data.installed[name].version === fileData) {
return apps.errout({
error: "This application is already installed at version " + text.cyan +
fileData + text.nocolor + ". To continue uninstall the application and try agai" +
"n: " + text.green + "biddle uninstall " + name + text.nocolor,
name : "biddle_install_getlate"
});
}
flag.late = true;
if (flag.zip === true && flag.hash === true) {
compareHash();
}
});
};
apps.list = function biddle_list() {
var listtype = {},
dolist = function biddle_list_dolist(type) {
var len = 0,
a = 0,
proper = (type === "published")
? "Published"
: (data.internal === true)
? text.bold + text.red + "Internally" + text.none + text.cyan + " installed"
: "Installed",
vert = (type === "published")
? "latest"
: "version",
loct = (type === "published")
? "directory"
: "location",
pads = {},
pad = function biddle_list_dolist_pad(item, col) {
var b = item.length;
if (b === pads[col]) {
return item;
}
do {
item = item + " ";
b = b + 1;
} while (b < pads[col]);
return item;
};
listtype[type].sort();
if (listtype[type].length === 0) {
console.log(
text.underline + text.cyan + proper + " applications:" + text.none
);
console.log("");
if (data.internal === true) {
console.log(
"No " + text.bold + text.red + "internal" + text.none + " applications are " +
type + " by biddle."
);
} else {
console.log("No applications are " + type + " by biddle.");
}
console.log("");
} else {
console.log(
text.underline + text.cyan + proper + " applications:" + text.none
);
console.log("");
len = listtype[type].length;
pads.name = 0;
pads.version = 0;
a = 0;
do {
if (listtype[type][a].length > pads.name) {
pads.name = listtype[type][a].length;
}
if (data[type][listtype[type][a]][vert].length > pads.version) {
pads.version = data[type][listtype[type][a]][vert].length;
}
a = a + 1;
} while (a < len);
a = 0;
do {
console.log(
"* " + text.cyan + pad(listtype[type][a], "name") + text.nocolor + " - " + pad(data[type][listtype[type][a]][vert], "version") +
" - " + data[type][listtype[type][a]][loct]
);
a = a + 1;
} while (a < len);
console.log("");
}
};
if (data.internal === true) {
data.input[2] = "installed";
} else if (data.input[2] !== "installed" && data.input[2] !== "published" && data.input[2] !== undefined) {
data.input[2] = "both";
}
listtype = {
installed: Object.keys(data.installed),
published: Object.keys(data.published)
};
console.log("");
if (data.input[2] === "installed" || data.input[2] === "both" || data.input[2] === undefined) {
dolist("installed");
}
if (data.input[2] === "published" || data.input[2] === "both" || data.input[2] === undefined) {
dolist("published");
}
};
apps.makedir = function biddle_makedir(dirToMake, callback) {
node
.fs
.stat(dirToMake, function biddle_makedir_stat(err, stats) {
var dirs = [],
ind = 0,
len = 0,
ers = "",
restat = function biddle_makedir_stat_restat() {
node
.fs
.stat(
dirs.slice(0, ind + 1).join(node.path.sep),
function biddle_makedir_stat_restat_callback(erra, stata) {
var erras = "";
ind = ind + 1;
if (erra !== null) {
erras = erra.toString();
if (erras.indexOf("no such file or directory") > 0 || erra.code === "ENOENT") {
return node
.fs
.mkdir(
dirs.slice(0, ind).join(node.path.sep),
function biddle_makedir_stat_restat_callback_mkdir(errb) {
if (errb !== null && errb.toString().indexOf("file already exists") < 0) {
return apps.errout(
{error: errb, name: "biddle_makedir_stat_restat_callback_mkdir"}
);
}
if (ind < len) {
biddle_makedir_stat_restat();
} else {
callback();
}
}
);
}
if (erras.indexOf("file already exists") < 0) {
return apps.errout({error: erra, name: "biddle_makedir_stat_restat_callback"});
}
}
if (stata.isFile() === true) {
return apps.errout({
error: "Destination directory, '" + dirToMake + "', is a file.",
name : "biddle_makedir_stat_restat_callback"
});
}
if (ind < len) {
biddle_makedir_stat_restat();
} else {
callback();
}
}
);
};
if (err !== null) {
ers = err.toString();
if (ers.indexOf("no such file or directory") > 0 || err.code === "ENOENT") {
dirs = dirToMake.split(node.path.sep);
if (dirs[0] === "") {
ind = ind + 1;
}
len = dirs.length;
return restat();
}
if (ers.indexOf("file already exists") < 0) {
return apps.errout({error: err, name: "biddle_makedir_stat"});
}
}
if (stats.isFile() === true) {
return apps.errout({
error: "Destination directory, '" + dirToMake + "', is a file.",
name : "biddle_makedir_stat"
});
}
callback();
});
};
apps.markdown = function biddle_markdown() {
var file = data.abspath + "readme.md",
size = data.input[2];
if (data.command === "markdown") {
file = data.input[2];
size = data.input[3];
}
node
.fs
.readFile(file, "utf8", function biddle_markdown_readfile(err, readme) {
var lines = [],
listly = [],
output = [],
para = false,
ind = "",
listr = "",
b = 0,
len = 0,
bullet = "",
codeblock = function biddle_markdown_readfile_blockcode() {
var blocks = "",
spaces = "nospace",
removespaces = function biddle_markdown_readfile_removespaces(x) {
if (spaces === "nospace") {
spaces = x;
}
return x.slice(spaces.length);
},
blockstart = function biddle_markdown_readfile_blockstart() {
var bs = lines[b].replace(/\s+/g, ""),
bsout = function biddle_markdown_readfile_blockstart_bsout(x) {
return x;
};
return bs.replace(/((~+)|(`+))/, bsout);
};
lines[b].replace(/^(\s+)/, removespaces);
if (spaces === "nospace") {
spaces = "";
}
blocks = blockstart();
output.push("");
b = b + 1;
if (b < len) {
if (lines[b].replace(/^(\s+)/, "").indexOf(blocks) === 0 && (/^(\s*((`{3,})|(~{3,}))+)/).test(lines[b]) === true) {
output.push("");
} else {
lines[b] = text.green + lines[b].replace(/^(\s+)/, removespaces) + text.nocolor;
do {
if (lines[b].indexOf(blocks) > -1 && (/(((`{3,})|(~{3,}))+\s*)$/).test(lines[b]) === true) {
lines[b] = "";
output.push("");
break;
}
output.push(
ind + text.green + lines[b].replace(/^(\s+)/, removespaces) + text.nocolor
);
b = b + 1;
} while (b < len);
spaces = "nospace";
}
}
},
hr = function biddle_markdown_readfile_hr(block) {
var item = lines[b]
.replace(/\s+/, "")
.charAt(0),
out = "",
maxx = size - block.length,
inc = 0;
do {
inc = inc + 1;
out = out + item;
} while (inc < maxx);
lines[b] = block + out;
para = false;
},
parse = function biddle_markdown_readfile_parse(item, listitem, cell) {
var block = false,
chars = [],
final = 0,
s = (/\s/),
x = 0,
y = ind.length,
start = 0,
index = 0,
math = 0,
quote = "",
wrap = function biddle_markdown_readfile_parse_wrap(tick) {
var z = x,
format = function biddle_markdown_readfile_parse_wrap_format(eol) {
if (block === true) {
chars[eol] = "\n" + ind + "| ";
} else {
chars[eol] = "\n" + ind;
}
index = y + eol;
if (chars[eol - 1] === " ") {
chars[eol - 1] = "";
} else if (chars[eol + 1] === " ") {
chars.splice(eol + 1, 1);
final = final - 1;
}
};
math = y + 2;
if (cell === true) {
return;
}
if (tick === true) {
do {
z = z - 1;
} while (chars[z + 1].indexOf(text.green) < 0 && z > index);
if (z > index) {
format(z);
}
} else if (s.test(chars[x]) === true) {
format(x);
} else {
do {
z = z - 1;
} while (s.test(chars[z]) === false && z > index);
if (z > index) {
format(z);
}
}
};
if (lines[b - 1] === "" && (/\u0020{4}\S/).test(item) === true && listitem === false) {
item = text.green + item + text.nocolor;
return item;
}
if (item.charAt(0) === ">") {
block = true;
}
if (listitem === true) {
item = item.replace(/^\s+/, "");
}
if ((/^(\s*>-+\s*)$/).test(item) === true) {
lines[b] = item.replace(/^(\s*>\s*)/, "");
hr(ind + " | ");
return lines[b];
}
chars = item
.replace(/^(\s*>\s*)/, ind + "| ")
.replace(/`/g, "bix~")
.split("");
final = chars.length;
if (cell === true) {
start = 0;
} else {
if (block === true) {
chars.splice(0, 0, " ");
}
if (listitem === true || block === true) {
x = listly.length;
do {
x = x - 1;
y = y + 4;
ind = ind + " ";
} while (x > 0);
}
if (block === false) {
if (listitem === true) {
chars.splice(0, 0, ind.slice(2));
} else {
chars.splice(0, 0, ind);
}
}
if (listitem === true) {
start = 2;
} else {
start = y - 1;
}
}
y = ind.length + 4;
if (listitem === true) {
math = y + 8;
} else {
math = y;
}
for (x = start; x < final; x = x + 1) {
if (quote === "") {
if (chars[x] === "*" && chars[x + 1] === "*") {
quote = "**";
chars.splice(x, 2);
chars[x] = text.bold + chars[x];
final = final - 2;
} else if (chars[x] === "_" && chars[x + 1] === "_") {
quote = "__";
chars.splice(x, 2);
chars[x] = text.bold + chars[x];
final = final - 2;
} else if (chars[x] === "*" && ((x === start && chars[x + 1] !== " ") || x > start)) {
quote = "*";
chars.splice(x, 1);
chars[x] = text.yellow + chars[x];
final = final - 1;
} else if ((x === start || (/\s/).test(chars[x - 1]) === true) && chars[x] === "_" && ((x === start && chars[x + 1] !== " ") || x > start)) {
quote = "_";
chars.splice(x, 1);
chars[x] = text.yellow + chars[x];
final = final - 1;
} else if (chars[x] === "b" && chars[x + 1] === "i" && chars[x + 2] === "x" && chars[x + 3] === "~") {
quote = "`";
chars.splice(x, 4);
chars[x] = text.green + chars[x];
final = final - 4;
} else if (chars[x - 2] === "," && chars[x - 1] === " " && chars[x] === "(") {
quote = ")";
chars[x] = chars[x] + text.cyan;
}
} else if (chars[x] === "b" && chars[x + 1] === "i" && chars[x + 2] === "x" && chars[x + 3] === "~" && quote === "`") {
quote = "";
chars.splice(x, 4);
if (chars[x] === undefined) {
x = chars.length - 1;
}
chars[x] = chars[x] + text.nocolor;
final = final - 4;
if (math > size && chars[x + 1] === " ") {
x = x + 1;
wrap(false);
}
} else if (chars[x] === ")" && quote === ")") {
quote = "";
chars[x] = text.nocolor + chars[x];
if (math > size && chars[x + 1] === " ") {
x = x + 1;
wrap(false);
}
} else if (chars[x] === "*" && chars[x + 1] === "*" && quote === "**") {
quote = "";
chars.splice(x, 2);
chars[x - 1] = chars[x - 1] + text.normal;
final = final - 2;
} else if (chars[x] === "*" && quote === "*") {
quote = "";
chars.splice(x, 1);
chars[x - 1] = chars[x - 1] + text.nocolor;
final = final - 1;
} else if (chars[x] === "_" && chars[x + 1] === "_" && quote === "__") {
quote = "";
chars.splice(x, 2);
chars[x - 1] = chars[x - 1] + text.normal;
final = final - 2;
} else if (chars[x] === "_" && (x + 1 === final || (/\s/).test(chars[x + 1]) === true) && quote === "_") {
quote = "";
chars.splice(x, 1);
chars[x - 1] = chars[x - 1] + text.nocolor;
final = final - 1;
}
if (math > size) {
if (quote === "`") {
wrap(true);
} else {
wrap(false);
}
}
if (chars[x + 1] === undefined) {
break;
}
math = math + 1;
}
if (quote === "**") {
chars.pop();
chars[x - 1] = chars[x - 1] + text.normal;
} else if (quote === "*") {
chars.pop();
chars[x - 1] = chars[x - 1] + text.none;
} else if (quote === ")") {
chars[x - 1] = chars[x - 1] + text.nocolor;
} else if (quote === "`") {
chars.pop();
chars[x - 4] = chars[x - 4] + text.nocolor;
chars[x - 3] = "";
chars[x - 2] = "";
chars[x - 1] = "";
chars[x] = "";
}
item = chars.join("");
if (block === true) {
ind = ind.slice(2);
} else if (listitem === true) {
ind = ind.slice(listly.length * 2);
}
return item;
},
table = function biddle_markdown_readfile_table() {
var rows = [
lines[b]
.replace(/^\|/, "")
.replace(/\|$/, "")
.split("|")
],
lens = rows[0].length,
cols = [],
c = 0,
d = 0,
e = 0,
lend = 0,
line = "";
c = b + 2;
line = lines[c]
.replace(/^\|/, "")
.replace(/\|$/, "");
d = 0;
do {
rows[0][d] = parse(rows[0][d].replace(/\s+/g, " ").replace(/^\s/, "").replace(
/\s$/,
""
), false, true);
lend = rows[0][d]
.replace(/\u001b\[\d+m/g, "")
.length;
cols.push(lend);
d = d + 1;
} while (d < lens);
if (line.indexOf("|") > -1) {
do {
rows.push(line.split("|").slice(0, lens));
d = 0;
do {
rows[rows.length - 1][d] = parse(
rows[rows.length - 1][d].replace(/\s+/g, " ").replace(
/^\s/,
""
).replace(/\s$/, ""),
false,
true
);
lend = rows[rows.length - 1][d]
.replace(/\u001b\[\d+m/g, "")
.length;
if (lend > cols[d]) {
cols[d] = lend;
}
if (rows[rows.length - 1][d] === "\u2713") {
rows[rows.length - 1][d] = text.bold + text.green + "\u2713" + text.none;
} else if (rows[rows.length - 1][d] === "X") {
rows[rows.length - 1][d] = text.bold + text.red + "X" + text.none;
} else if (rows[rows.length - 1][d] === "?") {
rows[rows.length - 1][d] = text.bold + text.yellow + "?" + text.none;
}
d = d + 1;
} while (d < lens);
c = c + 1;
if (c === len) {
break;
}
line = lines[c]
.replace(/^\|/, "")
.replace(/\|$/, "");
} while (line.indexOf("|") > -1);
}
c = 0;
lend = rows.length;
do {
d = 0;
do {
e = rows[c][d]
.replace(/\u001b\[\d+m/g, "")
.length;
if (d === lens - 1 && rows[c][d].length < cols[d]) {
do {
e = e + 1;
rows[c][d] = rows[c][d] + " ";
} while (e < cols[d]);
} else {
do {
e = e + 1;
rows[c][d] = rows[c][d] + " ";
} while (e < cols[d] + 1);
}
if (c === 0) {
if (d > 0) {
rows[c][d] = text.underline + " " + rows[c][d] + text.normal;
} else {
rows[c][d] = ind + text.underline + rows[c][d] + text.normal;
}
} else {
if (d > 0) {
rows[c][d] = " " + rows[c][d];
} else {
rows[c][d] = ind + rows[c][d];
}
}
d = d + 1;
} while (d < lens);
output.push(rows[c].join(""));
c = c + 1;
b = b + 1;
} while (c < lend);
b = b + 1;
para = false;
},
headings = function biddle_markdown_readfile_headings(color, level) {
if (level === 1) {
ind = "";
} else if (level === 2) {
ind = " ";
} else if (level === 3) {
ind = " ";
} else if (level === 4) {
ind = " ";
} else if (level === 5) {
ind = " ";
} else if (level === 6) {
ind = " ";
}
listly = [];
lines[b] = lines[b].replace(/^(\s*#+\s+)/, "");
if ((/(\\#)/).test(lines[b]) === true) {
lines[b] = lines[b].replace(/\\#/g, "#");
} else {
lines[b] = lines[b].replace(/(\s*#*\s*)$/, "");
}
lines[b] = ind.slice(2) + text.underline + text.bold + text[color] + lines[b] +
text.none;
para = false;
};
if (err !== null && err !== undefined) {
return apps.errout({error: err, name: "biddle_markdown_readfile"});
}
readme = (function biddle_markdown_readfile_removeImages() {
var readout = [],
j = readme.split(""),
i = 0,
ilen = j.length,
brace = "",
code = (j[0] === " " && j[1] === " " && j[2] === " " && j[3] === " ");
for (i = 0; i < ilen; i = i + 1) {
if (brace === "") {
if (j[i] === "\r") {
if (j[i + 1] === "\n") {
j[i] = "";
} else {
j[i] = "\n";
}
if (j[i + 1] === "`" && j[i + 2] === "`" && j[i + 3] === "`") {
code = true;
brace = "```";
} else if (j[i + 1] === " " && j[i + 2] === "`" && j[i + 3] === "`" && j[i + 4] === "`") {
code = true;
brace = "```";
} else if (j[i + 1] === " " && j[i + 2] === " " && j[i + 3] === "`" && j[i + 4] === "`" && j[i + 5] === "`") {
code = true;
brace = "```";
} else if (j[i + 1] === " " && j[i + 2] === " " && j[i + 3] === " " && j[i + 4] === "`" && j[i + 5] === "`" && j[i + 6] === "`") {
code = true;
brace = "```";
} else if (j[i + 1] === " " && j[i + 2] === " " && j[i + 3] === " " && j[i + 4] === " ") {
code = true;
} else {
code = false;
}
} else if (j[i] === "\n") {
if (j[i + 1] === "`" && j[i + 2] === "`" && j[i + 3] === "`") {
code = true;
brace = "```";
} else if (j[i + 1] === " " && j[i + 2] === "`" && j[i + 3] === "`" && j[i + 4] === "`") {
code = true;
brace = "```";
} else if (j[i + 1] === " " && j[i + 2] === " " && j[i + 3] === "`" && j[i + 4] === "`" && j[i + 5] === "`") {
code = true;
brace = "```";
} else if (j[i + 1] === " " && j[i + 2] === " " && j[i + 3] === " " && j[i + 4] === "`" && j[i + 5] === "`" && j[i + 6] === "`") {
code = true;
brace = "```";
} else if (j[i + 1] === " " && j[i + 2] === " " && j[i + 3] === " " && j[i + 4] === " ") {
code = true;
} else {
code = false;
}
} else if (j[i] === "`") {
brace = "`";
code = true;
} else if (j[i] === "!" && j[i + 1] === "[") {
brace = "]";
j[i] = "";
j[i + 1] = "";
} else if (j[i] === "]" && j[i + 1] === "(") {
j[i] = ", ";
} else if (j[i] === "[" && code === false) {
j[i] = "";
} else if (j[i] === ")" && j[i + 1] === " " && (/\s/).test(j[i + 2]) === false) {
j[i] = "),";
}
} else if (brace === j[i]) {
if (brace === "`") {
code = false;
} else {
j[i] = "";
}
if (brace === "]" && j[i + 1] === "(") {
brace = ")";
} else {
brace = "";
}
} else if (brace === "```" && j[i] === "`" && j[i + 1] === "`" && j[i + 2] === "`" && (/((\r|\n)(\u0020|\t)*)$/).test(j.slice(i - 4, i)) === true) {
code = false;
brace = "";
}
if (brace !== ")") {
readout.push(j[i]);
}
}
return readout.join("");
}());
lines = readme.split("\n");
len = lines.length;
output.push("");
for (b = 0; b < len; b = b + 1) {
if ((/^(\s*)$/).test(lines[b]) === true) {
lines[b] = "";
para = false;
} else if ((/^((\*|-|_){3})$/).test(lines[b].replace(/\s+/g, "")) === true && (/^(\s{0,3})/).test(lines[b]) === true && (lines[b].indexOf("-") < 0 || lines[b - 1].length < 1)) {
hr("");
} else if ((/-{3,}\s*\|\s*-{3,}/).test(lines[b + 1]) === true) {
table();
} else if ((/^(\s*((`{3,})|(~{3,}))+)/).test(lines[b]) === true) {
codeblock();
} else if ((/^(\s{0,3}#{6,6}\s)/).test(lines[b]) === true) {
headings("purple", 6);
} else if ((/^(\s{0,3}#{5,5}\s)/).test(lines[b]) === true) {
headings("blue", 5);
} else if ((/^(\s{0,3}#{4,4}\s)/).test(lines[b]) === true) {
headings("yellow", 4);
} else if ((/^(\s{0,3}#{3,3}\s)/).test(lines[b]) === true) {
headings("green", 3);
} else if ((/^(\s{0,3}#{2,2}\s)/).test(lines[b]) === true) {
headings("cyan", 2);
} else if ((/^(\s{0,3}#\s)/).test(lines[b]) === true) {
headings("red", 1);
} else if ((/^(\s{0,3}=+\s*)$/).test(lines[b + 1]) === true && (/^(\s{0,3}>)/).test(lines[b]) === false && (/^(\s*)$/).test(lines[b]) === false) {
headings("red", 1);
lines.splice(b + 1, 1);
len = len - 1;
} else if ((/^(\s{0,3}-+\s*)$/).test(lines[b + 1]) === true && (/^(\s{0,3}>)/).test(lines[b]) === false && (/^(\s*)$/).test(lines[b]) === false) {
headings("cyan", 2);
lines.splice(b + 1, 1);
len = len - 1;
} else if ((/^(\s*(\*|-)\s)/).test(lines[b]) === true) {
listr = (/^(\s*)/).exec(lines[b])[0];
if (listly.length === 0 || listly[listly.length - 1] < listr.length) {
if ((/\s/).test(listr.charAt(0)) === true) {
listly.push(listr.length);
} else {
listly = [listr.length];
}
} else if (listly.length > 1 && listr.length < listly[listly.length - 1]) {
do {
listly.pop();
} while (listly.length > 1 && listr.length < listly[listly.length - 1]);
}
if (listly.length % 2 > 0) {
bullet = "*";
} else {
bullet = "-";
}
lines[b] = parse(lines[b], true, false).replace(
/\*|-/,
text.bold + text.red + bullet + text.none
);
para = true;
} else if (lines[b].indexOf(" ") === 0) {
lines[b] = text.green + lines[b] + text.nocolor;
} else if ((/^\s*>/).test(lines[b]) === true) {
listly = [];
lines[b] = parse(lines[b], false, false);
if (b < len - 1 && (/^(\s*)$/).test(lines[b + 1]) === false) {
lines[b + 1] = ">" + lines[b + 1];
}
para = true;
} else if (para === true) {
listly = [];
len = len - 1;
b = b - 1;
output.pop();
lines[b] = lines[b] + lines[b + 1];
lines.splice(b + 1, 1);
lines[b] = parse(
lines[b].replace(/\s+/g, " ").replace(/^\s/, ""),
false,
false
);
para = true;
} else {
para = true;
listly = [];
lines[b] = parse(lines[b], false, false);
}
output.push(lines[b]);
}
if (output[output.length - 1] === undefined) {
output.pop();
}
output[output.length - 1] = output[output.length - 1] + text.none;
if (data.platform === "win32") {
ind = output.join("\r\n");
} else {
ind = output.join("\n");
}
if ((data.command === "help" && data.input[3] === "test") || (data.command === "markdown" && data.input[4] === "test")) {
ind = "\"" + ind
.replace(/\r\n/g, "\n")
.slice(0, 8192)
.replace(/(\\(\w+)?)$/, "")
.replace(/\\(?!(\\))/g, "\\\\")
.replace(/\n/g, "\\n")
.replace(/"/g, "\\\"")
.replace(/\\\\"/g, "\\\"")
.replace(/(\s+)$/, "")
.replace(/(\\n)$/, "")
.replace(/\u001b\[39m\u001b\[0m/g, "\" + text.none + \"")
.replace(/\u001b\[0m/g, "\" + text.normal + \"")
.replace(/\u001b\[1m/g, "\" + text.bold + \"")
.replace(/\u001b\[4m/g, "\" + text.underline + \"")
.replace(/\u001b\[31m/g, "\" + text.red + \"")
.replace(/\u001b\[32m/g, "\" + text.green + \"")
.replace(/\u001b\[33m/g, "\" + text.yellow + \"")
.replace(/\u001b\[34m/g, "\" + text.blue + \"")
.replace(/\u001b\[35m/g, "\" + text.purple + \"")
.replace(/\u001b\[36m/g, "\" + text.cyan + \"")
.replace(/\u001b\[39m/g, "\" + text.nocolor + \"")
.replace(/\u0020\+\u0020""\u0020\+\u0020/g, " + ") + "\"";
}
console.log(ind);
process.exit(0);
});
};
apps.publish = function biddle_publish() {
var filedata = [],
varlen = 0,
publoc = "",
primaryzip = "",
pjsonname = (data.input[2] === undefined)
? data.abspath + "package.json"
: apps.relToAbs(
data.input[2].replace(/(\/|\\)$/, "") + node.path.sep + "package.json",
data.cwd
),
varnames = {},
variants = [],
indexfile = function biddle_publish_indexfile() {
var rows = [],
file = "
!!app name!! - P" +
"ublications !!app name!! - Publications
Cl" +
"ick on table headings to sort.
▼ Ve" +
"rsion | ▼ Date | ▼ Size | ▼ Variant Name▼ Zip File | ▼ Hash
!!row!!<" +
"td colspan=\"6\">biddle i" +
"nstall !!install!!
",
script = "(function(){var abspath=location.href.replace(/^(file:\\/\\/)/,\"\").replace(/" +
"(index\\.xhtml)$/,\"\"),headings=document.getElementsByTagName(\"thead\")[0].g" +
"etElementsByTagName(\"th\"),hlen=headings.length,a=0,start=1,sorter=function(h" +
"eading){var b=0,ind=0,len=headings.length,span=\"\",rows=[],rowlist=[],tbody=d" +
"ocument.getElementsByTagName(\"tbody\")[0],ascend=false,rowsort=function(a,b){" +
"var vala=\"\",valb=\"\";if(ind===1){vala=Number(a.getElementsByTagName(\"td\")" +
"[1].getAttribute(\"data-date\"));valb=Number(b.getElementsByTagName(\"td\")[1]" +
".getAttribute(\"data-date\"))}else if(ind===2){vala=Number(a.getElementsByTagN" +
"ame(\"td\")[2].getAttribute(\"data-size\"));valb=Number(b.getElementsByTagName" +
"(\"td\")[2].getAttribute(\"data-size\"))}else if(ind===5){vala=a.getElementsBy" +
"TagName(\"td\")[ind].getElementsByTagName(\"a\")[0].innerHTML.toLowerCase();va" +
"lb=b.getElementsByTagName(\"td\")[ind].getElementsByTagName(\"a\")[0].innerHTM" +
"L.toLowerCase()}else{vala=a.getElementsByTagName(\"td\")[ind].innerHTML.toLowe" +
"rCase();valb=b.getElementsByTagName(\"td\")[ind].innerHTML.toLowerCase()}if(as" +
"cend===true){if(vala>valb){return 1}else{return -1}}else{if(vala>valb){return " +
"-1}else{return 1}}};do{span=headings[b].getElementsByTagName(\"span\")[0];if(h" +
"eading===headings[b]){ind=b;if(span.style.visibility===\"visible\"){if(span.in" +
"nerHTML===\"â–²\"){span.innerHTML=\"â–¼\"}else{span.innerHTML=\"â–²\"}}else{span.sty" +
"le.visibility=\"visible\"}if(span.innerHTML===\"â–²\"){ascend=true;document.getE" +
"lementById(\"aria-arrow\").innerHTML=\"Sorting by \"+headings[b].lastChild.tex" +
"tContent+\" ascending\"}else{ascend=false;document.getElementById(\"aria-arrow" +
"\").innerHTML=\"Sorting by \"+headings[b].lastChild.textContent+\" descending" +
"\"}}else{span.style.visibility=\"hidden\"}b=b+1}while(b" + primaryzip
);
if (typeof data.packjson.author === "string") {
file = file.replace(
" <",
" <"
);
}
filedata.forEach(function biddle_publish_indexfile_filedata(val) {
var build = [],
monthval = val
.date
.slice(4, 6),
month = {
"01": "January",
"02": "February",
"03": "March",
"04": "April",
"05": "May",
"06": "June",
"07": "July",
"08": "August",
"09": "September",
"10": "October",
"11": "November",
"12": "December"
},
varname = (val.variant === "")
? "Full Application"
: val.variant;
build.push("");
build.push(val.version);
build.push(" | ");
build.push(val.date.slice(6));
build.push("\u0020");
build.push(month[monthval]);
build.push("\u0020");
build.push(val.date.slice(0, 4));
build.push(" | ");
build.push(apps.commas(Number(val.size)));
build.push(" | ");
build.push(varname);
build.push(" | ");
build.push(val.filename);
build.push(" | ");
build.push(val.hash);
build.push(" |
");
rows.push(build.join(""));
});
file = file.replace(/\!\!row\!\!/, rows.join(""));
apps.writeFile(
file,
publoc + "index.xhtml",
function biddle_publish_indexfile_readIndex_index_writeXhtml() {
return true;
}
);
apps.writeFile(
script,
publoc + "biddlesort.js",
function biddle_publish_indexfile_readIndex_writeScript() {
return true;
}
);
},
zippy = function biddle_publish_zippy_init() {
return;
},
variantsDir = function biddle_publish_variantsDir(value) {
var varobj = (value === "biddletempprimary")
? {}
: data
.packjson
.publication_variants[value];
value = apps.sanitizef(value);
varnames[value] = true;
if (typeof varobj.exclusions !== "object" || typeof varobj.exclusions.join !== "function") {
varobj.exclusions = [];
}
varobj.exclusions = varobj
.exclusions
.concat(data.ignore);
varobj
.exclusions
.sort();
apps.copy(
data.input[2],
data.abspath + "temp" + node.path.sep + value,
varobj.exclusions,
function biddle_publish_variantsDir_copy() {
var complete = function biddle_publish_variantsDir_copy_complete() {
var location = data.abspath + "temp" + node.path.sep + value,
valname = (value === "biddletempprimary")
? ""
: value;
zippy({location: location, name: valname});
},
tasks = function biddle_publish_variantsDir_copy_tasks() {
node.child(
varobj.tasks[0],
function biddle_publish_variantsDir_copy_tasks_child(ert, stdoutt, stdert) {
var len = varobj.tasks.length - 1;
if (ert !== null) {
console.log(
text.bold + text.red + "Error:" + text.none + " with variant " + value + " on p" +
"ublish task"
);
console.log(varobj.tasks[0]);
console.log(ert);
} else if (stdert !== null && stdert !== "") {
console.log(
text.bold + text.red + "Error:" + text.none + " with variant " + value + " on p" +
"ublish task"
);
console.log(varobj.tasks[0]);
console.log(stdert);
} else {
console.log(
text.bold + text.green + "Complete:" + text.none + " with variant " + value + " on publish task"
);
console.log(varobj.tasks[0]);
console.log(stdoutt);
}
varobj
.tasks
.splice(0, 1);
if (len > 0) {
biddle_publish_variantsDir_copy_tasks();
} else {
complete();
}
}
);
};
if (varobj.tasks === "object" && varobj.tasks.length > 0) {
tasks();
} else {
complete();
}
}
);
},
execution = function biddle_publish_execution() {
variants.push("biddletempprimary");
varnames.biddletempprimary = true;
varlen = (data.latestVersion === true)
? variants.length * 2
: variants.length;
apps.makedir("temp", function biddle_publish_execution_variantDir() {
if (data.parallel === true) {
variants.forEach(variantsDir);
} else {
variantsDir("biddletempprimary");
}
});
},
preexec = function biddle_publish_preexec() {
if (data.address.target.indexOf(node.path.sep + "publications") + 1 === data.address.target.length - 13) {
data.address.target = data.address.target + apps.sanitizef(data.packjson.name) +
node.path.sep;
}
apps.makedir(data.address.target, function biddle_publish_preexec_makedir() {
if (data.latestVersion === true) {
varlen = varlen * 2;
data
.published[data.packjson.name]
.latest = data.packjson.version;
apps.writeFile(
data.packjson.version,
data.address.target + "latest.txt",
function biddle_zip_makedir_latestTXT() {
execution();
}
);
} else {
execution();
}
});
};
zippy = function biddle_publish_zippy(vardata) {
apps.zip(function biddle_publish_zippy_zip(zipfilename) {
node
.fs
.stat(zipfilename, function biddle_publish_zippy_zip_stat(erstat, stats) {
var filename = zipfilename
.split(node.path.sep)
.pop(),
safevars = filename
.replace(data.packjson.name, "")
.split("_"),
variant = "",
sdate = new Date(),
year = String(sdate.getUTCFullYear()),
month = String(sdate.getMonth() + 1),
day = String(sdate.getDate());
if (erstat !== null) {
return apps.errout({error: erstat, name: "biddle_publish_zippy_zip_stat"});
}
if (typeof stats !== "object") {
return apps.errout(
{error: "stats is not an object, from node.fs.stat", name: "biddle_publish_zippy_zip_stat"}
);
}
if (month.length < 2) {
month = "0" + month;
}
if (day.length < 2) {
day = "0" + day;
}
if (safevars.length > 2) {
variant = safevars[1];
}
apps.hash(zipfilename, "hashFile", function biddle_publish_zippy_zip_hash() {
var hashname = zipfilename.replace(".zip", ".hash"),
a = variants.length;
apps.remove(hashname, function biddle_publish_zippy_zip_hash_remove() {
apps.writeFile(
data.hashFile,
hashname,
function biddle_publish_zippy_zip_hash_remove_writehash() {
if (vardata.name === "" && (primaryzip === "" || zipfilename.indexOf("_latest.zip") > 0)) {
primaryzip = filename;
}
filedata.push({
date : year + month + day,
filename: filename,
hash : data.hashFile,
size : stats.size,
variant : variant,
version : data.packjson.version
});
varlen = varlen - 1;
if (varlen < 1) {
apps.writeFile(
JSON.stringify(data.published),
data.abspath + "published.json",
function biddle_publish_zippy_zip_hash_writeJSON() {
apps.remove(
data.abspath + "temp",
function biddle_publish_zippy_zip_hash_writeJSON_removeTemp() {
return true;
}
);
}
);
node
.fs
.readFile(
publoc + "filedata.json",
function biddle_publish_zippy_zip_stat_readfiledata(erd, catalogue) {
var parsed = {},
x = 0;
if (erd !== null && erd !== "") {
if (erd.toString().indexOf("no such file or directory") > 0) {
apps.writeFile(
JSON.stringify({filedata: filedata}),
publoc + "filedata.json",
function biddle_publish_zippy_zip_stat_readfiledata_writeNew() {
return true;
}
);
return indexfile();
}
return apps.errout(
{error: erd, name: "biddle_publish_zippy_zip_stat_readfiledata"}
);
}
parsed = JSON.parse(catalogue);
x = parsed.filedata.length - 1;
do {
if (parsed.filedata[x].filename.indexOf("_latest.zip") === parsed.filedata[x].filename.length - 11) {
parsed
.filedata
.splice(x, 1);
}
x = x - 1;
} while (x > -1);
filedata = filedata.concat(parsed.filedata);
apps.writeFile(
JSON.stringify({filedata: filedata}),
publoc + "filedata.json",
function biddle_publish_zippy_zip_stat_readfiledata_write() {
return true;
}
);
indexfile();
}
);
}
}
);
});
if (data.parallel === false) {
do {
a = a - 1;
if (variants[a] === vardata.name || (variants[a] === "biddletempprimary" && vardata.name === "")) {
variants.splice(a, 1);
a = variants.length;
if (a > 0) {
return variantsDir(variants[variants.length - 1]);
}
break;
}
} while (a > 0);
}
});
});
}, vardata);
};
apps.getpjson(pjsonname, function biddle_publish_callback() {
if (data.published[data.packjson.name] !== undefined && data.published[data.packjson.name].versions.indexOf(data.packjson.version) > -1) {
return apps.errout({
error: "Attempted to publish " + data.packjson.name + " over existing version " +
text.bold + text.red + data.packjson.version + text.none,
name : "biddle_publish_execution"
});
}
data.packjson.name = apps.sanitizef(data.packjson.name);
if (data.input[3] === undefined || data.address.target !== apps.relToAbs(data.input[3], data.cwd) + node.path.sep) {
publoc = data.address.publications + apps.sanitizef(data.packjson.name) + node.path.sep;
} else {
publoc = data.address.target + apps.sanitizef(data.packjson.name) + node.path.sep;
}
data.address.target = publoc;
if (data.published[data.packjson.name] !== undefined && data.input[3] !== undefined) {
data.input = data
.input
.slice(0, 3);
} else if (data.published[data.packjson.name] === undefined) {
data.published[data.packjson.name] = {};
data
.published[data.packjson.name]
.versions = [];
data
.published[data.packjson.name]
.latest = "";
data
.published[data.packjson.name]
.directory = data.address.target;
}
data
.published[data.packjson.name]
.versions
.push(data.packjson.version);
data.latestVersion = (function biddle_publish_callback_latestVersion() {
var ver = "",
sem = [],
cur = [],
len = 0,
a = 0;
if (ver.indexOf("alpha") > -1 || ver.indexOf("beta") > -1) {
return false;
}
if (data.published[data.packjson.name].latest === "") {
return true;
}
ver = data.packjson.version;
sem = ver.split(".");
cur = data
.published[data.packjson.name]
.latest
.split(".");
if (sem.length === 1 && cur.length === 1 && sem.indexOf("-") > 0) {
sem = sem[0].split("-");
cur = cur[0].split("-");
}
len = (Math.max(sem, cur));
do {
if (isNaN(sem[a]) === false && isNaN(cur[a]) === false) {
if (Number(sem[a]) > Number(cur[a])) {
return true;
}
if (Number(cur[a]) < Number(sem[a])) {
return false;
}
}
if (sem[a] === undefined) {
return true;
}
if (cur[a] === undefined) {
return false;
}
if (isNaN(cur[a]) === true && isNaN(sem[a]) === false) {
return false;
}
a = a + 1;
} while (a < len);
return true;
}());
variants = (typeof data.packjson.publication_variants === "object")
? Object.keys(data.packjson.publication_variants)
: [];
preexec();
});
};
apps.readBinary = function biddle_readBinary(filePath, callback) {
var size = 0,
fdescript = 0,
writeBinary = function biddle_readBinary_writeBinary() {
node
.fs
.open(
data.address.downloads + node.path.sep + data.fileName,
"w",
function biddle_readBinary_writeBinary_writeopen(errx, fd) {
var buffer = new Buffer(size);
if (errx !== null) {
return apps.errout(
{error: errx, name: "biddle_readBinary_writeBinary_writeopen"}
);
}
node
.fs
.read(
fdescript,
buffer,
0,
size,
0,
function biddle_readBinary_writeBinary_writeopen_read(erry, ready, buffy) {
if (erry !== null) {
return apps.errout(
{error: erry, name: "biddle_readBinary_writeBinary_writeopen_read"}
);
}
if (ready > 0) {
node
.fs
.write(
fd,
buffy,
0,
size,
function biddle_readBinary_writeBinary_writeopen_read_write(errz, written, buffz) {
if (errz !== null) {
return apps.errout(
{error: errz, name: "biddle_readBinary_writeBinary_writeopen_read_write"}
);
}
if (written < 1) {
return apps.errout({
error: "Reading binary file " + filePath + " but 0 bytes were read.",
name : "biddle_readBinary_writeBinary_writeopen_read_write"
});
}
callback(buffz.toString("utf8", 0, written));
}
);
}
}
);
}
);
};
node
.fs
.stat(filePath, function biddle_readBinary_stat(errs, stats) {
if (errs !== null) {
return apps.errout({error: errs, name: "biddle_readBinary_stat"});
}
size = stats.size;
node
.fs
.open(filePath, "r", function biddle_readyBinary_stat_open(erro, fd) {
var length = (stats.size < 100)
? stats.size
: 100,
buffer = new Buffer(length);
fdescript = fd;
if (erro !== null) {
return apps.errout({error: erro, name: "biddle_readBinary_stat_open"});
}
node
.fs
.read(
fd,
buffer,
0,
length,
1,
function biddle_readyBinary_stat_open_read(errr, read, buff) {
var bstring = "";
if (errr !== null) {
return apps.errout({error: errr, name: "biddle_readBinary_stat_open_read"});
}
bstring = buff.toString("utf8", 0, buff.length);
bstring = bstring.slice(2, bstring.length - 2);
if ((/[\u0002-\u0008]|[\u000e-\u001f]/).test(bstring) === true) {
writeBinary();
} else {
node
.fs
.readFile(
filePath,
"utf8",
function biddle_readBinary_stat_open_read_readFile(errf, fileData) {
if (errf !== null && errf !== undefined) {
return apps.errout(
{error: errf, name: "biddle_readBinary_stat_open_read_readFile"}
);
}
if ((data.command === "update" || data.command === "install") && (/(\.hash)$/).test(filePath) === true) {
data.hashFile = fileData;
callback(fileData);
} else if (data.command === "status") {
callback(fileData, filePath);
} else if ((data.command === "update" || data.command === "install") && (/(latest\.txt)$/).test(filePath) === true) {
callback(fileData);
} else {
apps.writeFile(fileData, apps.sanitizef(filePath), callback);
}
}
);
}
return read;
}
);
});
});
};
apps.readlist = function biddle_readlist() {
var datalist = "";
if (data.command === "publish" || (data.command === "list" && data.input[2] === "published")) {
datalist = "published";
} else if (data.command === "installed" || data.command === "status" || (data.command === "list" && data.input[2] === "installed")) {
datalist = "installed";
} else {
return apps.errout(
{error: "Unqualified operation: readlist() but command is not published or installed.", name: "biddle_readlist"}
);
}
node
.fs
.readFile(
datalist + ".json",
"utf8",
function biddle_readlist_readFile(err, fileData) {
var jsondata = JSON.parse(fileData);
if (err !== null && err !== undefined) {
return apps.errout({error: err, name: "biddle_readlist_readFile"});
}
data[datalist] = jsondata[datalist];
data.status[datalist] = true;
}
);
};
apps.relToAbs = function biddle_relToAbs(filepath, reference) {
var abs = reference
.replace(/((\/|\\)+)$/, "")
.split(node.path.sep),
rel = filepath
.replace(/\\|\//g, node.path.sep)
.split(node.path.sep),
cur = data
.cwd
.split(node.path.sep),
a = 0,
b = 0,
reftest = false;
if (data.platform === "win32") {
if ((/^(\w:\\)/).test(filepath) === true) {
return filepath;
}
if ((/^(\w:\\)/).test(reference) === true) {
reftest = true;
}
} else {
if (filepath.charAt(0) === "/") {
return filepath;
}
if (reference.charAt(0) === "/") {
reftest = true;
}
}
if (data.cwd !== reference && reftest === false) {
if (abs[0] === "..") {
do {
cur.pop();
abs.splice(0, 1);
} while (cur[0] === "..");
} else if (cur[0] === ".") {
cur.splice(0, 1);
}
abs = cur.concat(abs);
}
if (rel[0] === "..") {
do {
abs.pop();
rel.splice(0, 1);
} while (rel[0] === "..");
} else if (rel[0] === ".") {
rel.splice(0, 1);
}
b = rel.length;
if (b < 0) {
do {
rel[a] = apps.sanitizef(rel[a]);
a = a + 1;
} while (a < b);
}
return abs.join(node.path.sep) + node.path.sep + rel.join(node.path.sep);
};
apps.remove = function biddle_remove(filepath, callback) {
var numb = {
dirs: 0,
file: 0,
othr: 0,
size: 0,
symb: 0
},
dirs = {},
util = {},
verbose = true;
if (data.command === "copy") {
verbose = false;
}
util.complete = function biddle_remove_complete() {
var out = ["biddle removed "];
if (data.command === "remove") {
out.push(text.red);
out.push(text.bold);
out.push(numb.dirs);
out.push(text.none);
out.push(" director");
if (numb.dirs === 1) {
out.push("y, ");
} else {
out.push("ies, ");
}
out.push(text.red);
out.push(text.bold);
out.push(numb.file);
out.push(text.none);
out.push(" file");
if (numb.dirs !== 1) {
out.push("s");
}
out.push(", ");
out.push(text.red);
out.push(text.bold);
out.push(numb.symb);
out.push(text.none);
out.push(" symbolic link");
if (numb.symb !== 1) {
out.push("s");
}
out.push(", and ");
out.push(text.red);
out.push(text.bold);
out.push(numb.symb);
out.push(text.none);
out.push(" other type");
if (numb.symb !== 1) {
out.push("s");
}
out.push(" at ");
out.push(text.red);
out.push(text.bold);
out.push(apps.commas(numb.size));
out.push(text.none);
out.push(" bytes.");
console.log(out.join(""));
console.log("Removed " + text.cyan + filepath + text.nocolor);
}
callback();
};
util.destroy = function biddle_remove_destroy(item, dir) {
node
.fs
.unlink(item, function biddle_remove_destroy_callback(er) {
if (verbose === true && er !== null && er.toString("no such file or directory") < 0) {
return apps.errout({error: er, name: "biddle_remove_delete_callback"});
}
if (item === dir) {
util.complete();
}
dirs[dir] = dirs[dir] - 1;
if (dirs[dir] < 1) {
util.rmdir(dir);
}
});
};
util.readdir = function biddle_remove_readdir(item) {
node
.fs
.readdir(item, function biddle_remove_readdir_callback(er, files) {
if (verbose === true && er !== null && er.toString("no such file or directory") < 0) {
return apps.errout({error: er, name: "biddle_remove_readdir_callback"});
}
dirs[item] = 0;
if (files === undefined || files.length < 1) {
util.rmdir(item);
} else {
files.forEach(function biddle_remove_readdir_callback_each(value) {
dirs[item] = dirs[item] + 1;
util.stat(item + node.path.sep + value, item);
});
}
});
};
util.rmdir = function biddle_remove_rmdir(item) {
node
.fs
.rmdir(item, function biddle_remove_delete_callback_rmdir(er) {
var dirlist = item.split(node.path.sep),
dir = "";
if (er !== null && er.toString().indexOf("resource busy or locked") > 0) {
return setTimeout(function biddle_remove_rmdir_delay() {
biddle_remove_rmdir(item);
}, 1000);
}
if (verbose === true && er !== null && er.toString("no such file or directory") < 0) {
return apps.errout({error: er, name: "biddle_remove_rmdir_callback"});
}
delete dirs[item];
if (Object.keys(dirs).length < 1) {
util.complete();
} else {
dirlist.pop();
dir = dirlist.join(node.path.sep);
dirs[dir] = dirs[dir] - 1;
if (dirs[dir] < 1) {
biddle_remove_rmdir(dir);
}
}
});
};
util.stat = function biddle_remove_stat(item, dir) {
node
.fs
.lstat(item, function biddle_remove_stat_callback(er, stats) {
if (verbose === true && er !== null && er.toString().indexOf("no such file or directory") < 0) {
return apps.errout({error: er, name: "biddle_remove_stat_callback"});
}
if (stats !== undefined && stats.isFile !== undefined) {
if (stats.isDirectory() === true) {
numb.dirs = numb.dirs + 1;
util.readdir(item);
} else {
if (stats.isFile() === true) {
numb.file = numb.file + 1;
numb.size = numb.size + stats.size;
} else if (stats.isSymbolicLink() === true) {
numb.symb = numb.symb + 1;
} else {
numb.othr = numb.othr + 1;
}
util.destroy(item, dir);
}
} else if (item === dir) {
if (data.command === "remove") {
console.log("Item not found - " + text.cyan + filepath + text.nocolor);
}
callback();
}
});
};
util.stat(filepath, filepath);
};
apps.sanitizef = function biddle_sanitizef(filePath) {
var paths = filePath.split(node.path.sep),
fileName = paths.pop();
paths.push(fileName.replace(/\+|<|>|:|"|\||\?|\*|%|\s/g, ""));
return paths.join("");
};
apps.status = function biddle_status(app, forceInternal, callback) {
var list = [],
versions = {},
a = 0,
b = 0,
len = 0,
single = false,
appdata = (forceInternal === true)
? data.installed.internal
: data.installed,
addy = "",
compare = function biddle_status_compare() {
var keys = Object.keys(versions),
klen = keys.length,
k = 0,
currents = [],
outs = [];
keys.sort();
do {
if (appdata[keys[k]].version === versions[keys[k]]) {
currents.push(
"* " + keys[k] + " matches published version " + text.bold + text.green + versions[keys[k]] +
text.none
);
} else if (data.command === "update") {
outs.push(
"* Updating " + text.yellow + keys[k] + text.nocolor + " from version " + text.bold + text.cyan + appdata[keys[k]].version +
text.none + " to newer version " + text.bold + text.green + versions[keys[k]] +
text.none
);
} else {
outs.push(
"* " + keys[k] + " is installed at version " + text.bold + text.cyan + appdata[keys[k]].version +
text.none + " but published version is " + text.bold + text.red + versions[keys[k]] +
text.none
);
}
k = k + 1;
} while (k < klen);
klen = outs.length;
if (klen > 0) {
if (data.command === "status") {
if (single === false) {
console.log("");
if (currents.length < 1) {
console.log(
text.underline + text.red + "All Applications Outdated:" + text.none
);
} else {
console.log(text.underline + "Outdated Applications:" + text.normal);
}
}
console.log("");
}
k = 0;
do {
callback(outs[k]);
k = k + 1;
} while (k < klen);
}
klen = currents.length;
if (klen > 0) {
if (data.command === "status") {
if (single === false) {
console.log("");
if (outs.length < 1) {
console.log(
text.underline + text.green + "All Applications Are Current:" + text.none
);
} else {
console.log(text.underline + "Current Applications:" + text.normal);
}
}
console.log("");
}
k = 0;
do {
callback(currents[k]);
k = k + 1;
} while (k < klen);
}
},
getversion = function biddle_status_get(filedata, filepath) {
var name = function biddle_status_name(pub) {
var dirs = [];
if (data.protocoltest.test(pub) === true) {
dirs = pub.split("/");
dirs.pop();
return dirs.pop();
}
dirs = pub.split(node.path.sep);
dirs.pop();
if (dirs[dirs.length - 1] === "") {
dirs.pop();
}
return dirs.pop();
};
versions[name(filepath)] = filedata;
b = b + 1;
if (b === len) {
compare();
}
};
if (app === undefined || app === "") {
list = Object.keys(appdata);
if (data.childtest === false) {
list.push("biddle");
}
list.sort();
} else if (appdata[app] !== undefined) {
list = [app];
single = true;
} else if (app !== undefined) {
return apps.errout({
error: app + " is not a biddle installed application.",
name : "biddle_status"
});
}
len = list.length;
do {
if (list[a] === "biddle") {
apps.get(
"http://prettydiff.com/downloads/biddle/latest.txt",
"latest.txt",
getversion
);
} else {
addy = appdata[list[a]].published;
if (data.protocoltest.test(addy) === true) {
apps.get(addy + "/latest.txt", "latest.txt", getversion);
} else {
apps.get(addy + node.path.sep + "latest.txt", "latest.txt", getversion);
}
}
a = a + 1;
} while (a < len);
};
apps.test = function biddle_test() {
var loc = "",
test = "",
file = (data.input[2] === undefined)
? data.abspath + "package.json"
: apps.relToAbs(
data.input[2].replace(/(\/|\\)$/, "") + node.path.sep + "package.json",
data.cwd
),
name = data.input[2],
spawn = function biddle_test_spawn() {
var spwn = require("child_process").spawn,
args = test.split(" "),
cmd = args[0],
exec = function biddle_test_spawn_init() {
return true;
};
args.splice(0, 1);
exec = spwn(cmd, args, {
cwd : loc,
stdio: "inherit"
});
if (exec.stdout !== null) {
exec
.stdout
.on("data", function biddle_test_spawn_data(data) {
console.log(data);
});
}
if (exec.stderr !== null) {
exec
.stderr
.on("data", function biddle_test_spawn_stderr(data) {
console.log(data);
});
}
exec.on("error", function biddle_test_spawn_error(data) {
apps.errout({error: data, name: "biddle_test_spawn_error"});
});
exec.on("close", function biddle_test_spawn_close() {
console.log(
"biddle has completed test for " + name + "."
);
});
},
foreign = function biddle_test_foreign() {
loc = name;
test = data.packjson.test;
if (test === undefined) {
return apps.errout({
error: name + " does not have a test property in its package.json",
name : "biddle_test_foreign"
});
}
spawn();
};
if (name === undefined || name === "" || name === "biddle") {
data.input[2] = "biddle";
return apps.testBiddle();
}
if (name.indexOf(node.path.sep) < 0) {
if (data.installed[name] === undefined) {
return apps.errout({
error: name + " is not a biddle installed appliation. For local directories try ." +
node.path.sep + name,
name : "biddle_test"
});
}
loc = data
.installed[name]
.location;
test = data
.installed[name]
.test;
spawn();
} else {
apps.getpjson(file, foreign);
}
};
apps.testBiddle = function biddle_testBiddle() {
var startTime = Date.now(),
order = [
"moduleInstall",
"lint",
"hashString",
"hashFile",
"copy",
"remove",
"markdown",
"get",
"zip",
"unzip",
"publishA",
"publishB",
"install",
"listStatus",
"republish",
"update",
"uninstall",
"unpublishLatest",
"unpublishAll",
"unpublishB"
],
phasenumb = 0,
options = {
correct : false,
crlf : false,
html : true,
inchar : " ",
insize : 4,
lang : "javascript",
methodchain : false,
mode : "beautify",
nocaseindent: false,
objsort : "all",
preserve : true,
styleguide : "jslint",
wrap : 80
},
//Windows child shell does not see a user modified path variable
childcmd = (data.platform === "win32")
? "node " + data.abspath + "biddle "
: (data.abspath === process.cwd() + node.path.sep)
? "node " + data.abspath + "biddle "
: "biddle ",
mods = {},
testpath = data.abspath + "unittest",
humantime = function biddle_test_humantime(finished) {
var minuteString = "",
hourString = "",
secondString = "",
finalMem = "",
minutes = 0,
hours = 0,
elapsed = 0,
memory = {},
prettybytes = function biddle_test_humantime_prettybytes(an_integer) {
//find the string length of input and divide into triplets
var length = an_integer
.toString()
.length,
triples = (function biddle_test_humantime_prettybytes_triples() {
if (length < 22) {
return Math.floor((length - 1) / 3);
}
//it seems the maximum supported length of integer is 22
return 8;
}()),
//each triplet is worth an exponent of 1024 (2 ^ 10)
power = (function biddle_test_humantime_prettybytes_power() {
var a = triples - 1,
b = 1024;
if (triples === 0) {
return 0;
}
if (triples === 1) {
return 1024;
}
do {
b = b * 1024;
a = a - 1;
} while (a > 0);
return b;
}()),
//kilobytes, megabytes, and so forth...
unit = [
"",
"KB",
"MB",
"GB",
"TB",
"PB",
"EB",
"ZB",
"YB"
],
output = "";
if (typeof an_integer !== "number" || isNaN(an_integer) === true || an_integer < 0 || an_integer % 1 > 0) {
//input not a positive integer
output = "0.00B";
} else if (triples === 0) {
//input less than 1000
output = an_integer + "B";
} else {
//for input greater than 999
length = Math.floor((an_integer / power) * 100) / 100;
output = length.toFixed(2) + unit[triples];
}
return output;
},
plural = function biddle_test_humantime_plural(x, y) {
var a = "";
if (x !== 1) {
a = x + y + "s ";
} else {
a = x + y + " ";
}
return a;
},
minute = function biddle_test_humantime_minute() {
minutes = parseInt((elapsed / 60), 10);
minuteString = (finished === true)
? plural(minutes, " minute")
: (minutes < 10)
? "0" + minutes
: "" + minutes;
minutes = elapsed - (minutes * 60);
secondString = (finished === true)
? (minutes === 1)
? " 1 second "
: minutes.toFixed(3) + " seconds "
: minutes.toFixed(3);
};
memory = process.memoryUsage();
finalMem = prettybytes(memory.rss);
//last line for additional instructions without bias to the timer
elapsed = (Date.now() - startTime) / 1000;
secondString = elapsed.toFixed(3);
if (elapsed >= 60 && elapsed < 3600) {
minute();
} else if (elapsed >= 3600) {
hours = parseInt((elapsed / 3600), 10);
elapsed = elapsed - (hours * 3600);
hourString = (finished === true)
? plural(hours, " hour")
: (hours < 10)
? "0" + hours
: "" + hours;
minute();
} else {
secondString = (finished === true)
? plural(secondString, " second")
: secondString;
}
if (finished === true) {
if (data.platform === "win32") {
hourString = "\n" + hourString;
} else {
hourString = "\r\n" + hourString;
}
return finalMem + " of memory consumed" + hourString + minuteString +
secondString + "total time";
}
if (hourString === "") {
hourString = "00";
}
if (minuteString === "") {
minuteString = "00";
}
if ((/^([0-9]\.)/).test(secondString) === true) {
secondString = "0" + secondString;
}
return text.cyan + "[" + hourString + ":" + minuteString + ":" +
secondString + "]" + text.nocolor + " ";
},
diffFiles = function biddle_test_diffFiles(
sampleName,
sampleSource,
sampleDiff
) {
var aa = 0,
pdlen = 0,
report = [],
plural = "s";
options.mode = "diff";
options.source = sampleSource.replace(/\u001b/g, "\\u001b");
options.diff = sampleDiff.replace(/\u001b/g, "\\u001b");
options.diffcli = true;
options.context = 2;
options.lang = "text";
report = mods.prettydiff(options);
pdlen = report.length;
if (pdlen === 1) {
plural = "";
} else if (pdlen < 1) {
console.log("");
if (sampleSource.length < 1) {
console.log(
text.red + "An empty source value passed into test diff operation." + text.nocolor
);
}
if (sampleDiff.length < 1) {
console.log(
text.red + "An empty diff value passed into test diff operation." + text.nocolor
);
}
return apps.errout({
error : text.red + "bad diff, output is 0 characters long" + text.nocolor,
name : sampleName,
stdout: "",
time : humantime(true)
});
}
console.log(
text.red + "Test Failure with Comparison" + text.nocolor
);
console.log(text.underline + "First Sample" + text.normal);
console.log(sampleSource);
console.log("");
console.log(text.underline + "Second Sample" + text.normal);
console.log(sampleDiff);
console.log("");
console.log(text.underline + "Comparison" + text.normal);
// report indexes from diffcli feature of diffview.js
// 0. source line number
// 1. source code line
// 2. diff line number
// 3. diff code line
// 4. change
// 5. index of options.context (not parallel) 6 - total count of differences
for (aa = 0; aa < pdlen; aa = aa + 1) {
console.log(report[aa]);
}
console.log("");
console.log(
global.prettydiff.meta.difftotal + text.cyan + " difference" + plural + " count" +
"ed." + text.nocolor
);
console.log("");
apps.errout({
error : "Pretty Diff " + text.red + "failed" + text.nocolor + " in function: " + text.cyan +
sampleName + text.nocolor,
name : sampleName,
stdout: "",
time : humantime(true)
});
},
phases = {},
next = function biddle_test_next() {
console.log("");
if (order.length < 1) {
return apps.remove(testpath, function biddle_test_next_rmdir() {
console.log("All tasks complete... Exiting clean!");
console.log(humantime(true));
process.exit(0);
});
}
if (order[0] === "moduleInstall") {
data.internal = true;
} else {
data.internal = false;
}
phases[order[0]]();
order.splice(0, 1);
};
phases.copy = function biddle_test_copy() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Copy tests");
node.child(
childcmd + "copy " + data.abspath + "test" + node.path.sep + "biddletesta" +
node.path.sep + "biddletesta.js " + testpath + " childtest",
{
cwd: data.abspath
},
function biddle_test_copy_child(er, stdout, stder) {
var copytest = "biddle copied " + text.green + text.bold + "0" + text.none + " " +
"directories, " + text.green + text.bold + "1" + text.none + " file, and " +
text.green + text.bold + "0" + text.none + " symbolic links at " + text.green +
text.bold + "23,177" + text.none + " bytes.\nCopied " + text.cyan + data.abspath +
"test" + node.path.sep + "biddletesta" + node.path.sep + "biddletesta.js" +
text.nocolor + " to " + text.green + data.abspath + "unittest" + text.nocolor,
copyfile = data.abspath + "unittest" + node.path.sep + "biddletesta.js";
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_copy_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_copy_child", stdout: stdout, time: humantime(true)}
);
}
stdout = stdout
.replace(/(\s+)$/, "")
.replace(/\r\n/g, "\n");
if (stdout !== copytest) {
return diffFiles("biddle_test_copy_child", stdout, copytest);
}
node
.fs
.stat(copyfile, function biddle_test_copy_child_stat(ers, stats) {
if (ers !== null) {
return apps.errout(
{error: ers, name: "biddle_test_copy_child_stat", stdout: stdout, time: humantime(true)}
);
}
if (stats === undefined || stats.isFile() === false) {
return apps.errout({
error : "copy failed as " + copyfile + " is not present",
name : "biddle_test_copy_child_stat",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + "copy test passed." + text.nocolor
);
next();
});
}
);
};
phases.get = function biddle_test_get() {
var flag = {
binary: false,
text : false
};
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Get tests");
node.child(
childcmd + "get https://www.google.com/images/branding/googlelogo/2x/googlelogo" +
"_color_272x92dp.png " + data.abspath + "unittest childtest",
{
cwd: data.abspath
},
function biddle_test_get_childText(er, stdout, stder) {
var size = "",
sizenumb = "",
sizetest = " \u001b[1m\u001b[32m13,504\u001b[39m\u001b[0m";
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_get_childText", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_get_childText", stdout: stdout, time: humantime(true)}
);
}
size = stdout
.slice(stdout.indexOf("written at") + 10)
.replace(/(\s+)$/, "");
if ((/^(((File)|(\d{3}))\u0020)/).test(stdout) === false || stdout.indexOf("File\u0020") < 0 || stdout.indexOf(" 0 bytes") > 0 || size.replace(" bytes.", "").length < 4) {
return apps.errout({
error: "Unexpected output for test 'get':\r\n" + text.red + stdout + text.nocolor,
name : "biddle_test_get_childText",
time : humantime(true)
});
}
size = size
.replace("\r\n", "\n")
.slice(0, size.indexOf("\n"));
sizenumb = size.replace(/\sbytes\.?/, "");
if (sizenumb !== sizetest) {
return diffFiles("biddle_test_get_childText", sizenumb, sizetest);
}
console.log(
humantime(false) + " " + text.green + "get text test passed." + text.nocolor +
" File written at" + size
);
flag.text = true;
if (flag.binary === true) {
next();
}
}
);
node.child(
childcmd + "get https://www.google.com/images/nav_logo242.png " + data.abspath +
"unittest childtest",
{
cwd: data.abspath
},
function biddle_test_get_childBinary(er, stdout, stder) {
var size = "",
sizenumb = "",
sizetest = " \u001b[1m\u001b[32m16,786\u001b[39m\u001b[0m";
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_get_childBinary", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_get_childBinary", stdout: stdout, time: humantime(true)}
);
}
size = stdout
.slice(stdout.indexOf("written at") + 10)
.replace(/(\s+)$/, "");
if ((/^(((File)|(\d{3}))\u0020)/).test(stdout) === false || stdout.indexOf("File\u0020") < 0 || stdout.indexOf(" 0 bytes") > 0 || size.replace(" bytes.", "").length < 4) {
return apps.errout({
error: "Unexpected output for test 'get':\r\n" + text.red + stdout + text.nocolor,
name : "biddle_test_get_childBinary",
time : humantime(true)
});
}
size = size
.replace("\r\n", "\n")
.slice(0, size.indexOf("\n"));
sizenumb = size.replace(/\sbytes\.?/, "");
if (sizenumb !== sizetest) {
return diffFiles("biddle_test_get_childBinary", sizenumb, sizetest);
}
console.log(
humantime(false) + " " + text.green + "get binary test passed." + text.nocolor +
" File written at" + size
);
flag.binary = true;
if (flag.text === true) {
next();
}
}
);
};
phases.hashFile = function biddle_test_hashFile() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Hash file test");
node.child(
childcmd + "hash " + data.abspath + "LICENSE childtest",
{
cwd: data.abspath
},
function biddle_test_hashFile_child(er, stdout, stder) {
var hashtest = "be09a71a2cda28b74e9dd206f46c1621aebe29182723f191d8109db4705ced014de469043c397f" +
"ee4d8f3483e396007ca739717af4bf43fed4c2e3dd14f3dc0c";
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_hashFile_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_hashFile_child", stdout: stdout, time: humantime(true)}
);
}
stdout = stdout.replace(/((\r?\n)+)$/, "");
if (stdout !== hashtest) {
return diffFiles("biddle_test_hashFile_child", stdout, hashtest);
}
console.log(
humantime(false) + " " + text.green + "hash file test passed." + text.nocolor
);
next();
}
);
};
phases.hashString = function biddle_test_hashString() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Hash string test");
node.child(
childcmd + "hash string \"a moderately long string to hash and test in the unit" +
" tests of biddle\" childtest",
{
cwd: data.abspath
},
function biddle_test_hashString_child(er, stdout, stder) {
var hashtest = "d18faf161f06a2362ba0efbc4a66f8e85f500b6281c848f6775c587362808e3f51ff557a20a544" +
"c41660f5d92fc018020c74b035d1eef4954828bc4125c2a11d";
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_hashString_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_hashString_child", stdout: stdout, time: humantime(true)}
);
}
stdout = stdout.replace(/((\r?\n)+)$/, "");
if (stdout !== hashtest) {
return diffFiles("biddle_test_hashString_child", stdout, hashtest);
}
console.log(
humantime(false) + " " + text.green + "hash string test passed." + text.nocolor
);
next();
}
);
};
phases.install = function biddle_test_install() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Install tests");
node.child(
childcmd + "install " + data.abspath + "publications" + node.path.sep + "biddle" +
"testa" + node.path.sep + "biddletesta_latest.zip childtest",
{
cwd: data.abspath
},
function biddle_test_install_child(er, stdout, stder) {
var instfile = data.abspath + "applications" + node.path.sep + "biddletesta" +
node.path.sep + "liba" + node.path.sep + "libab.txt";
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_install_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_install_child", stdout: stdout, time: humantime(true)}
);
}
if (stdout.indexOf(
"is missing the " + text.cyan + "http(s)" + text.nocolor + " scheme, treating a" +
"s a local path..."
) < 7) {
return apps.errout({
error : "Expected output to contain: is missing the " + text.cyan + "http(s)" + text.nocolor +
" scheme, treating as a local path...",
name : "biddle_test_install_child",
stdout: stdout,
time : humantime(true)
});
}
node
.fs
.stat(instfile, function biddle_test_install_child_stat(err, stats) {
if (err !== null) {
return apps.errout(
{error: err, name: "biddle_test_install_child_stat", stdout: stdout, time: humantime(true)}
);
}
if (typeof stats !== "object" || stats.isFile() === false) {
return apps.errout({
error : instfile + " does not exist.",
name : "biddle_test_install_child_stat",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + "File from install is present:" + text.nocolor +
" " + instfile
);
node
.fs
.readFile(
data.abspath + "installed.json",
"utf8",
function biddle_test_install_child_stat_readJSON(era, filedata) {
var inst = {};
if (era !== null && era !== undefined) {
return apps.errout({
error : instfile + " does not exist.",
name : "biddle_test_install_child_stat_readJSON",
stdout: stdout,
time : humantime(true)
});
}
inst = JSON.parse(filedata);
if (inst.biddletesta === undefined) {
return apps.errout(
{error: "biddletesta is absent from installed.json", name: "biddle_test_install_child_stat_readJSON", stdout: stdout, time: humantime(true)}
);
}
if ((/^(99\.99\.\d{4})$/).test(inst.biddletesta.version) === false) {
return apps.errout({
error : "Expected biddletesta.version of installed.json to be equivalent to '99\\.99\\." +
"\\d{4}'.",
name : "biddle_test_install_child_stat_readJSON",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + "installed.json contains biddletesta." +
text.nocolor
);
console.log(
humantime(false) + " " + text.green + "install test passed." + text.nocolor
);
next();
}
);
});
}
);
};
phases.lint = function biddle_test_lint() {
var ignoreDirectory = [
".git",
"applications",
"bin",
"dependencies",
"downloads",
"internal",
"publications",
"unittest"
],
files = [],
lintrun = function biddle_test_lint_lintrun() {
var len = files.length,
a = 0,
failed = false,
lintit = function biddle_test_lint_lintrun_lintit() {
var result = {},
ecount = 0,
good = function biddle_tst_lint_lintrun_lintit_good() {
console.log(
humantime(false) + text.green + "Lint is good for file " + (
a + 1
) + ":" + text.nocolor + " " + files[a][0]
);
if (a === len - 1) {
console.log(text.green + "Lint operation complete!" + text.nocolor);
next();
}
},
report = function biddle_test_lint_lintrun_lintit_report(warning) {
//start with an exclusion list. There are some warnings that I don't care about
if (warning === null) {
return good();
}
if (warning.message.indexOf("Unexpected dangling '_'") === 0) {
return good();
}
if ((/Bad\u0020property\u0020name\u0020'\w+_'\./).test(warning.message) === true) {
return good();
}
if (warning.message.indexOf("/*global*/ requires") === 0) {
return good();
}
failed = true;
if (ecount === 0) {
console.log(text.red + "JSLint errors on" + text.nocolor + " " + files[a][0]);
console.log("");
}
ecount = ecount + 1;
console.log("On line " + warning.line + " at column: " + warning.column);
console.log(warning.message);
console.log("");
return apps.errout({
error: text.red + "Lint fail" + text.nocolor + " :(",
name : "biddle_test_lint_lintrun_lintit",
time : humantime(true)
});
};
options.source = files[a][1];
result = mods.jslint(mods.prettydiff(options), {"for": true});
if (result.ok === true) {
good();
} else {
result
.warnings
.forEach(report);
}
};
options = {
correct : false,
crlf : false,
html : true,
inchar : " ",
insize : 4,
lang : "javascript",
methodchain : false,
mode : "beautify",
nocaseindent: false,
objsort : "all",
preserve : true,
styleguide : "jslint",
wrap : 80
};
do {
lintit();
if (failed === true) {
break;
}
a = a + 1;
} while (a < len);
};
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Lint tests");
console.log(
"** Note that line numbers of error messaging reflects beautified code line."
);
ignoreDirectory.forEach(
function biddle_test_lint_absignore(value, index, array) {
array[index] = data.abspath + value;
}
);
(function biddle_test_lint_getFiles() {
var enddirs = 1,
endfiles = 0,
endread = 0,
startdirs = 1,
startfiles = 0,
startread = 0,
idLen = ignoreDirectory.length,
readFile = function biddle_test_lint_getFiles_readFile(filePath) {
node
.fs
.readFile(
filePath,
"utf8",
function biddle_test_lint_getFiles_readFile_callback(err, data) {
if (err !== null && err !== undefined) {
return apps.errout(
{error: err, name: "biddle_test_lint_getFiles_readFile_callback", time: humantime(false)}
);
}
files.push([filePath, data]);
endread = endread + 1;
if (endread === startread && endfiles === startfiles && enddirs === startdirs) {
lintrun();
}
}
);
},
readDir = function biddle_test_lint_getFiles_readDir(filepath) {
node
.fs
.readdir(
filepath,
function biddle_test_lint_getFiles_readDir_callback(erra, list) {
var fileEval = function biddle_test_lint_getFiles_readDir_callback_fileEval(
val
) {
var filename = (filepath.charAt(filepath.length - 1) === node.path.sep)
? filepath + val
: filepath + node.path.sep + val;
node
.fs
.stat(
filename,
function biddle_test_lint_getFiles_readDir_callback_fileEval_stat(errb, stat) {
var a = 0;
endfiles = endfiles + 1;
if (errb !== null) {
return apps.errout(
{error: errb, name: "biddle_test_lint_getFiles_readDir_callback_fileEval_stat", time: humantime(false)}
);
}
if (stat.isFile() === true && (/(\.js)$/).test(filename) === true) {
startread = startread + 1;
readFile(filename);
}
if (stat.isDirectory() === true) {
startdirs = startdirs + 1;
do {
if (filename === ignoreDirectory[a]) {
enddirs = enddirs + 1;
if (endread === startread && endfiles === startfiles && enddirs === startdirs) {
lintrun();
}
return;
}
a = a + 1;
} while (a < idLen);
enddirs = enddirs + 1;
biddle_test_lint_getFiles_readDir(filename);
}
}
);
};
if (erra !== null) {
return apps.errout({
error: "Error reading path: " + filepath + "\n" + erra,
name : "biddle_test_lint_getFiles_readDir_callback",
time : humantime(false)
});
}
startfiles = startfiles + list.length;
list.forEach(fileEval);
}
);
};
readDir(data.abspath);
}());
};
phases.listStatus = function biddle_test_listStatus() {
var listcmds = [
"install " + data.abspath + "unittest" + node.path.sep + "publications" +
node.path.sep + "biddletestb" + node.path.sep + "biddletestb_latest.zip",
"list",
"list published",
"list installed",
"status",
"status biddletesta",
"status biddletesta",
"status",
"uninstall biddletestb"
],
changed = false,
listChild = function biddle_test_listStatus_childWrapper() {
node.child(childcmd + listcmds[0] + " childtest", {
cwd: data.abspath
}, function biddle_test_listStatus_childWrapper_child(er, stdout, stder) {
var listout = "\n" + text.underline + text.cyan + "installed applications:" +
text.none + "\n\n* " + text.cyan + "biddletesta" + text.nocolor + " - 99.99.xxx" +
"x - " + data.abspath + "applications" + node.path.sep + "biddletesta" + node.path.sep +
"\n* " + text.cyan + "biddletestb" + text.nocolor + " - 98.98.1234 - " + data.abspath +
"applications" + node.path.sep + "biddletestb" + node.path.sep + "\n\n" +
text.underline + text.cyan + "published applications:" + text.none + "\n\n* " +
text.cyan + "biddletesta" + text.nocolor + " - 99.99.xxxx - " + data.abspath +
"publications" + node.path.sep + "biddletesta" + node.path.sep + "\n* " +
text.cyan + "biddletestb" + text.nocolor + " - 98.98.1234 - " + data.abspath +
"unittest" + node.path.sep + "publications" + node.path.sep + "biddletestb" +
node.path.sep,
listpub = "\n" + text.underline + text.cyan + "published applications:" +
text.none + "\n\n* " + text.cyan + "biddletesta" + text.nocolor + " - 99.99.xxx" +
"x - " + data.abspath + "publications" + node.path.sep + "biddletesta" + node.path.sep +
"\n* " + text.cyan + "biddletestb" + text.nocolor + " - 98.98.1234 - " + data.abspath +
"unittest" + node.path.sep + "publications" + node.path.sep + "biddletestb" +
node.path.sep,
listist = "\n" + text.underline + text.cyan + "installed applications:" +
text.none + "\n\n* " + text.cyan + "biddletesta" + text.nocolor + " - 99.99.xxx" +
"x - " + data.abspath + "applications" + node.path.sep + "biddletesta" + node.path.sep +
"\n* " + text.cyan + "biddletestb" + text.nocolor + " - 98.98.1234 - " + data.abspath +
"applications" + node.path.sep + "biddletestb" + node.path.sep,
statout = "\n" + text.underline + text.green +
"all applications are current:" + text.none + "\n\n* biddletesta matches publis" +
"hed version " + text.bold + text.green + "99.99.xxxx" + text.none + "\n* biddletestb mat" +
"ches published version " + text.bold + text.green + "98.98.1234" + text.none,
statpba = "\n* biddletesta matches published version " + text.bold + text.green +
"99.99.xxxx" + text.none,
statpbb = "\n" + text.underline + "outdated applications:" + text.normal + "\n" +
"\n* biddletesta is installed at version " + text.bold + text.cyan +
"99.99.xxxx" + text.none + " but published version is " + text.bold + text.red + "11.22.67" +
"89" + text.none + "\n\n" + text.underline + "current applications:" +
text.normal + "\n\n* biddletestb matches published version " + text.bold + text.green + "98." +
"98.1234" + text.none,
statpbc = "\n* biddletesta is installed at version " + text.bold + text.cyan + "99.99.xxxx" +
text.none + " but published version is " + text.bold + text.red + "11.22.6789" + text.none;
if (er !== null) {
return apps.errout({
error : er,
name : "biddle_test_listStatus_childWrapper_child(changed: " + changed + ", " +
listcmds[0] + ")",
stdout: stdout,
time : humantime(true)
});
}
if (stder !== null && stder !== "") {
return apps.errout({
error : stder,
name : "biddle_test_listStatus_childWrapper_child(changed: " + changed + ", " +
listcmds[0] + ")",
stdout: stdout,
time : humantime(true)
});
}
stdout = stdout
.toLowerCase()
.replace(/(\s+)$/, "")
.replace(/\r\n/g, "\n")
.replace(/99\.99\.\d{4}/g, "99.99.xxxx");
if (changed === false && listcmds[0] === "list") {
if (stdout !== listout) {
return diffFiles(
"biddle_test_listStatus_childWrapper_child(changed: " + changed + ", " +
listcmds[0] + ")",
stdout,
listout
);
}
console.log(
humantime(false) + " " + text.green + "mlist output passed." + text.nocolor
);
}
if (changed === false && listcmds[0] === "list published") {
if (stdout !== listpub) {
return diffFiles(
"biddle_test_listStatus_childWrapper_child(changed: " + changed + ", " +
listcmds[0] + ")",
stdout,
listpub
);
}
console.log(
humantime(false) + " " + text.green + "list published output passed." + text.nocolor
);
}
if (changed === false && listcmds[0] === "list installed") {
if (stdout !== listist) {
return diffFiles(
"biddle_test_listStatus_childWrapper_child(changed: " + changed + ", " +
listcmds[0] + ")",
stdout,
listist
);
}
console.log(
humantime(false) + " " + text.green + "list installed output passed." + text.nocolor
);
}
if (changed === false && listcmds[0] === "status") {
if (stdout !== statout) {
return diffFiles(
"biddle_test_listStatus_childWrapper_child(changed: " + changed + ", " +
listcmds[0] + ")",
stdout,
statout
);
}
console.log(
humantime(false) + " " + text.green + "status output passed." + text.nocolor
);
}
if (changed === true && listcmds[0] === "status") {
if (stdout !== statpbb) {
return diffFiles(
"biddle_test_listStatus_childWrapper_child(changed: " + changed + ", " +
listcmds[0] + ")",
stdout,
statpbb
);
}
console.log(
humantime(false) + " " + text.green + "status outdated output passed." + text.nocolor
);
}
if (changed === true && listcmds[0] === "status biddletesta") {
if (stdout !== statpbc) {
return diffFiles(
"biddle_test_listStatus_childWrapper_child(changed: " + changed + ", " +
listcmds[0] + ")",
stdout,
statpbc
);
}
console.log(
humantime(false) + " " + text.green + "status outdated biddletesta output passe" +
"d." + text.nocolor
);
}
if (changed === false && listcmds[0] === "status biddletesta") {
if (stdout !== statpba) {
return diffFiles(
"biddle_test_listStatus_childWrapper_child(changed: " + changed + ", " +
listcmds[0] + ")",
stdout,
statpba
);
}
console.log(
humantime(false) + " " + text.green + "status biddletesta output passed." +
text.nocolor
);
apps.writeFile(
"11.22.6789",
data.abspath + "publications" + node.path.sep + "biddletesta" + node.path.sep +
"latest.txt",
function biddle_test_listStatus_childWrapper_child_changeVersion() {
changed = true;
listcmds.splice(0, 1);
}
);
} else {
listcmds.splice(0, 1);
}
if (listcmds.length > 0) {
biddle_test_listStatus_childWrapper();
} else {
console.log(
humantime(false) + " " + text.green + "list and status tests passed." + text.nocolor
);
next();
}
});
};
phasenumb = phasenumb + 1;
console.log(phasenumb + ". List and status tests");
listChild();
};
phases.markdown = function biddle_test_markdown() {
var flag = {
"120": false,
"60" : false,
"80" : false
};
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Markdown tests");
node.child(
childcmd + "markdown " + data.abspath + "test" + node.path.sep +
"biddletesta" + node.path.sep + "READMEa.md 60 childtest",
{
cwd: data.abspath
},
function biddle_test_markdown_60(er, stdout, stder) {
var markdowntest = "\n" + text.underline + text.bold + text.red + "test README" + text.none + "\ns" +
"ome dummy subtext\n\n" + text.underline + text.bold + text.red + "heading by u" +
"nderline equals" + text.none + "\n\n" + text.underline + text.bold + text.cyan +
"heading by underline dashes" + text.none + "\n\n ===\n\n" + text.underline +
text.bold + text.cyan + "First Secondary Heading" + text.none + "\n | a big " +
"block quote lives here. This is where I am\n | going to experience with wra" +
"pping a block quote a bit\n | differently from other content. I need enoug" +
"h text\n | in this quote to wrap a couple of times, so I will\n | contin" +
"ue adding some nonsense and as long as it\n | takes to ensure I have a full" +
"y qualified test.\n | New line in a block quote\n | More block\n\n This" +
" is a regular paragraph that needs to be long\n enough to wrap a couple times" +
". This text will be unique\n from the text in the block quote because unique" +
"ness\n saves time when debugging test failures. I am now\n writing a bunch " +
"of wrapping paragraph gibberish, such as\n f324fasdaowkefsdva. That one isn'" +
"t even a word. It\n isn't cool if it doesn't contain a hyperlink,\n (" +
text.cyan + "http://tonowhwere.nothing" + text.nocolor +
"), in some text.\n\n " + text.bold + text.red + "*" + text.none + " list item" +
" 1 these also need to wrap like a\n paragraph. So blah blah wrapping some m" +
"adness into a\n list item right gosh darn here and let's see what\n shak" +
"es out of the coolness.\n " + text.bold + text.red + "*" + text.none + " list" +
" item 2 these also need to wrap like a\n paragraph. So blah blah wrapping s" +
"ome madness into a\n list item right gosh darn here and let's see what\n " +
" shakes out of the coolness.\n " + text.bold + text.red + "-" + text.none +
" sublist item 1 these also need to wrap\n like a paragraph. So blah blah " +
"wrapping some madness\n into a list item right gosh darn here and let's\n" +
" see what shakes out of the coolness.\n " + text.bold + text.red +
"-" + text.none + " sublist item 2 these also need to wrap\n like a paragr" +
"aph. So blah blah wrapping some madness\n into a list item right gosh dar" +
"n here and let's\n see what shakes out of the coolness.\n " + text.bold +
text.red + "*" + text.none + " subsublist item 1 these also need to\n wr" +
"ap like a paragraph. So blah blah wrapping some\n madness into a list i" +
"tem right gosh darn here\n and let's see what shakes out of the coolnes" +
"s.\n " + text.bold + text.red + "*" + text.none + " subsublist item 2 the" +
"se also need to\n wrap like a paragraph. So blah blah wrapping some\n " +
" madness into a list item right gosh darn here\n and let's see wha" +
"t shakes out of the coolness.\n " + text.bold + text.red + "*" + text.none +
" list item 3 these also need to wrap like a\n paragraph. So blah blah wrapp" +
"ing some madness into a\n list item right gosh darn here and let's see what" +
"\n shakes out of the coolness.\n " + text.bold + text.red + "-" + text.none +
" boo these also need to wrap like a\n paragraph. So blah blah wrapping so" +
"me madness into a\n list item right gosh darn here and let's see what\n " +
" shakes out of the coolness.\n\n " + text.underline + text.bold + text.green +
"First Tertiary Heading #####" + text.none + "\n This text should be extra i" +
"ndented.\n\n " + text.bold + text.red + "*" + text.none + " list item 1\n " +
" " + text.bold + text.red + "*" + text.none + " list item 2\n " + text.bold +
text.red + "-" + text.none + " sublist item 1\n " + text.bold + text.red +
"-" + text.none + " sublist item 2\n " + text.bold + text.red + "*" +
text.none + " subsublist item 1\n " + text.bold + text.red + "*" +
text.none + " subsublist item 2\n " + text.bold + text.red + "*" + text.none +
" list item 3\n " + text.bold + text.red + "-" + text.none +
" boo\n\n " + text.underline + text.bold + text.yellow + "Gettin Deep with t" +
"he Headings" + text.none + "\n\n | a big block quote lives here. This i" +
"s where I am\n | going to experience with wrapping a block quote\n " +
" | a bit differently from other content. I need\n | enough text in t" +
"his quote to wrap a couple of\n | times, so I will continue adding some" +
" nonsense\n | and a long a t takes to ensure I have a fully\n | " +
"qualified test.\n | New line in a block quote\n | More block and" +
" not a heading\n | --------------------------------------------------\n" +
"\n | a a a a a a a a a a a a a a a a a a a a a a a a a\n | a a a" +
" a a a a a a a a a a a a a a a a a a a a\n | a a a a a a a a a a a a a " +
"a a a a a a a a a a a\n\n | aa a a a a a a a a a a a a a a a a a a a a " +
"a a a\n | a a a a a a a a a a a a a a a a a a a a a a a a\n | a " +
"a a a a a a a a a a a a a a a a a a a a a a a\n\n Horizontal Rule with *" +
"\n************************************************************\n\n Horizo" +
"ntal Rule with - (requires an empty line between\n it and text)\n\n------" +
"------------------------------------------------------\n\n Horizontal Rul" +
"e with _\n____________________________________________________________\n\n " +
" Images get converted to their alt text description.\n\n This is a regul" +
"ar paragraph that needs to be long\n enough to wrap a couple times. This" +
" text will be\n unique from the text in the block quote because\n un" +
"iqueness saves time when debugging test failures. I\n am now writing a b" +
"unch of wrapping paragraph\n gibberish, such as f324fasdaowkefsdva. That" +
" one\n isn't even a word.\n\n " + text.bold + text.red + "*" +
text.none + " list item 1 these also need to wrap like\n a paragraph. So" +
" blah blah wrapping some\n madness into a list item right gosh darn her" +
"e and\n let's see what shakes out of the coolness.\n " + text.bold +
text.red + "*" + text.none + " list item 2 these also need to wrap like\n " +
" a paragraph. So blah blah wrapping some\n madness into a list item ri" +
"ght gosh darn here and\n let's see what shakes out of the coolness.\n " +
" " + text.bold + text.red + "-" + text.none + " sublist item 1 these also" +
" need to wrap\n like a paragraph. So blah blah wrapping some\n " +
" madness into a list item right gosh darn\n here and let's see what" +
" shakes out of the\n coolness.\n " + text.bold + text.red +
"-" + text.none + " sublist item 2 these also need to wrap\n like a pa" +
"ragraph. So blah blah wrapping some\n madness into a list item right " +
"gosh darn\n here and let's see what shakes out of the\n cool" +
"ness.\n " + text.bold + text.red + "*" + text.none + " subsublist ite" +
"m 1 these also need to\n wrap like a paragraph. So blah blah\n " +
" wrapping some madness into a list item right gosh\n darn her" +
"e and let's see what shakes out of\n the coolness.\n " +
text.bold + text.red + "*" + text.none + " subsublist item 2 these also need to" +
"\n wrap like a paragraph. So blah blah\n wrapping some m" +
"adness into a list item right gosh\n darn here and let's see what s" +
"hakes out of\n the coolness.\n " + text.bold + text.red + "*" +
text.none + " list item 3 these also need to wrap like\n a paragraph. So" +
" blah blah wrapping some\n madness into a list item right gosh darn her" +
"e and\n let's see what shakes out of the coolness.\n " + text.bold +
text.red + "-" + text.none + " boo these also need to wrap like a\n pa" +
"ragraph. So blah blah wrapping some madness\n into a list item right " +
"gosh darn here and let's\n see what shakes out of the coolness.\n\n " +
" " + text.underline + "Command " + text.normal + text.underline +
" Local " + text.normal + text.underline + " Argument Type " +
text.normal + text.underline + " Second Argument " + text.normal + "\n cop" +
"y " + text.bold + text.green + "✓" + text.none + " file path or dir" +
"ectory path directory path \n get " + text.bold + text.yellow +
"?" + text.none + " file path none \n gl" +
"obal " + text.bold + text.green + "✓" + text.none + " none " +
" none \n hash " + text.bold + text.green +
"✓" + text.none + " file path none \n he" +
"lp " + text.bold + text.green + "✓" + text.none + " number " +
" none \n install " + text.bold + text.yellow +
"?" + text.none + " zip file directory path \n li" +
"st " + text.bold + text.green + "✓" + text.none + " \"" + text.yellow +
"installed" + text.nocolor + "\" or \"" + text.yellow + "published" + text.nocolor +
"\" none \n markdown " + text.bold + text.green + "✓" +
text.none + " path to markdown file number \n publish " +
" " + text.bold + text.green + "✓" + text.none + " directory path " +
" directory path \n remove " + text.bold + text.green + "✓" +
text.none + " file path or directory path none \n status " +
" " + text.bold + text.yellow + "?" + text.none + " none or application " +
"name none \n test " + text.bold + text.red + "X" +
text.none + " none none \n uninstal" +
"l " + text.bold + text.green + "✓" + text.none + " application name " +
" none \n unpublish " + text.bold + text.green + "✓" +
text.none + " application name none \n unzip " +
" " + text.bold + text.green + "✓" + text.none + " path to zip file " +
" directory path \n zip " + text.bold + text.green + "✓\u001b[39m\u001b[0",
name = "biddle_test_markdown_60";
if (er !== null) {
return apps.errout(
{error: er, name: name, stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: name, stdout: stdout, time: humantime(true)}
);
}
stdout = stdout
.replace(/\r\n/g, "\n")
.slice(0, 8192)
.replace(/(\s+)$/, "")
.replace(/(\\(\w+)?\s*)$/, "");
if (stdout !== markdowntest) {
return diffFiles(name, stdout, markdowntest);
}
console.log(
humantime(false) + " " + text.green + "markdown 60 test passed." + text.nocolor
);
flag["60"] = true;
if (flag["80"] === true && flag["120"] === true) {
next();
}
}
);
node.child(
childcmd + "markdown " + data.abspath + "test" + node.path.sep +
"biddletesta" + node.path.sep + "READMEa.md 80 childtest",
{
cwd: data.abspath
},
function biddle_test_markdown_80(er, stdout, stder) {
var markdowntest = "\n" + text.underline + text.bold + text.red + "test README" + text.none + "\ns" +
"ome dummy subtext\n\n" + text.underline + text.bold + text.red + "heading by u" +
"nderline equals" + text.none + "\n\n" + text.underline + text.bold + text.cyan +
"heading by underline dashes" + text.none + "\n\n ===\n\n" + text.underline +
text.bold + text.cyan + "First Secondary Heading" + text.none + "\n | a big " +
"block quote lives here. This is where I am going to experience with\n | wra" +
"pping a block quote a bit differently from other content. I need\n | enoug" +
"h text in this quote to wrap a couple of times, so I will continue\n | addi" +
"ng some nonsense and as long as it takes to ensure I have a fully\n | quali" +
"fied test.\n | New line in a block quote\n | More block\n\n This is a r" +
"egular paragraph that needs to be long enough to wrap a couple\n times. This" +
" text will be unique from the text in the block quote because\n uniqueness sa" +
"ves time when debugging test failures. I am now writing a\n bunch of wrappin" +
"g paragraph gibberish, such as f324fasdaowkefsdva. That\n one isn't even a w" +
"ord. It isn't cool if it doesn't contain a hyperlink,\n (" + text.cyan + "ht" +
"tp://tonowhwere.nothing" + text.nocolor + "), in some text.\n\n " + text.bold +
text.red + "*" + text.none + " list item 1 these also need to wrap like a parag" +
"raph. So blah\n blah wrapping some madness into a list item right gosh darn" +
" here and\n let's see what shakes out of the coolness.\n " + text.bold +
text.red + "*" + text.none + " list item 2 these also need to wrap like a parag" +
"raph. So blah\n blah wrapping some madness into a list item right gosh darn" +
" here and\n let's see what shakes out of the coolness.\n " + text.bold +
text.red + "-" + text.none + " sublist item 1 these also need to wrap like a pa" +
"ragraph. So\n blah blah wrapping some madness into a list item right gosh" +
" darn here\n and let's see what shakes out of the coolness.\n " +
text.bold + text.red + "-" + text.none + " sublist item 2 these also need to wr" +
"ap like a paragraph. So\n blah blah wrapping some madness into a list ite" +
"m right gosh darn here\n and let's see what shakes out of the coolness.\n" +
" " + text.bold + text.red + "*" + text.none + " subsublist item 1 these a" +
"lso need to wrap like a paragraph.\n So blah blah wrapping some madness" +
" into a list item right gosh darn\n here and let's see what shakes out " +
"of the coolness.\n " + text.bold + text.red + "*" + text.none + " subsubl" +
"ist item 2 these also need to wrap like a paragraph.\n So blah blah wra" +
"pping some madness into a list item right gosh darn\n here and let's se" +
"e what shakes out of the coolness.\n " + text.bold + text.red + "*" + text.none +
" list item 3 these also need to wrap like a paragraph. So blah\n blah wrapp" +
"ing some madness into a list item right gosh darn here and\n let's see what" +
" shakes out of the coolness.\n " + text.bold + text.red + "-" + text.none +
" boo these also need to wrap like a paragraph. So blah blah\n wrapping so" +
"me madness into a list item right gosh darn here and let's\n see what sha" +
"kes out of the coolness.\n\n " + text.underline + text.bold + text.green + "F" +
"irst Tertiary Heading #####" + text.none + "\n This text should be extra in" +
"dented.\n\n " + text.bold + text.red + "*" + text.none +
" list item 1\n " + text.bold + text.red + "*" + text.none + " list item 2\n" +
" " + text.bold + text.red + "-" + text.none + " sublist item 1\n " +
text.bold + text.red + "-" + text.none + " sublist item 2\n " + text.bold +
text.red + "*" + text.none + " subsublist item 1\n " + text.bold +
text.red + "*" + text.none + " subsublist item 2\n " + text.bold + text.red +
"*" + text.none + " list item 3\n " + text.bold + text.red + "-" + text.none +
" boo\n\n " + text.underline + text.bold + text.yellow + "Gettin Deep with t" +
"he Headings" + text.none + "\n\n | a big block quote lives here. This i" +
"s where I am going to experience\n | with wrapping a block quote a bit " +
"differently from other content.\n | I need enough text in this quote to" +
" wrap a couple of times, so I\n | will continue adding some nonsense an" +
"d a long a t takes to ensure I\n | have a fully qualified test.\n " +
" | New line in a block quote\n | More block and not a heading\n " +
" | ----------------------------------------------------------------------\n\n " +
" | a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a" +
"\n | a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a" +
"\n | a a a a\n\n | aa a a a a a a a a a a a a a a a a a a a a a " +
"a a a a a a a a a a a a\n | a a a a a a a a a a a a a a a a a a a a a a" +
" a a a a a a a a a a a a\n | a a a a\n\n Horizontal Rule with *\n*" +
"******************************************************************************" +
"*\n\n Horizontal Rule with - (requires an empty line between it and text)" +
"\n\n--------------------------------------------------------------------------" +
"------\n\n Horizontal Rule with _\n______________________________________" +
"__________________________________________\n\n Images get converted to th" +
"eir alt text description.\n\n This is a regular paragraph that needs to b" +
"e long enough to wrap a couple\n times. This text will be unique from th" +
"e text in the block quote\n because uniqueness saves time when debugging " +
"test failures. I am now\n writing a bunch of wrapping paragraph gibberis" +
"h, such as\n f324fasdaowkefsdva. That one isn't even a word.\n\n " +
text.bold + text.red + "*" + text.none + " list item 1 these also need to wrap " +
"like a paragraph. So\n blah blah wrapping some madness into a list item" +
" right gosh darn here\n and let's see what shakes out of the coolness." +
"\n " + text.bold + text.red + "*" + text.none + " list item 2 these also " +
"need to wrap like a paragraph. So\n blah blah wrapping some madness int" +
"o a list item right gosh darn here\n and let's see what shakes out of t" +
"he coolness.\n " + text.bold + text.red + "-" + text.none + " sublist i" +
"tem 1 these also need to wrap like a paragraph.\n So blah blah wrappi" +
"ng some madness into a list item right gosh\n darn here and let's see" +
" what shakes out of the coolness.\n " + text.bold + text.red + "-" +
text.none + " sublist item 2 these also need to wrap like a paragraph.\n " +
" So blah blah wrapping some madness into a list item right gosh\n d" +
"arn here and let's see what shakes out of the coolness.\n " + text.bold +
text.red + "*" + text.none + " subsublist item 1 these also need to wrap like a" +
"\n paragraph. So blah blah wrapping some madness into a list item r" +
"ight\n gosh darn here and let's see what shakes out of the coolness" +
".\n " + text.bold + text.red + "*" + text.none + " subsublist item 2 " +
"these also need to wrap like a\n paragraph. So blah blah wrapping s" +
"ome madness into a list item right\n gosh darn here and let's see w" +
"hat shakes out of the coolness.\n " + text.bold + text.red + "*" + text.none +
" list item 3 these also need to wrap like a paragraph. So\n blah blah w" +
"rapping some madness into a list item right gosh darn here\n and let's " +
"see what shakes out of the coolness.\n " + text.bold + text.red + "-" +
text.none + " boo these also need to wrap like a paragraph. So blah blah\n " +
" wrapping some madness into a list item right gosh darn here and\n " +
" let's see what shakes out of the coolness.\n\n " + text.underline + "Co" +
"mmand " + text.normal + text.underline + " Local " + text.normal + text.underline +
" Argument Type " + text.normal + text.underline + " Second Argum" +
"ent " + text.normal + "\n copy " + text.bold + text.green + "✓" +
text.none + " file path or directory path directory path \n get " +
" " + text.bold + text.yellow + "?" + text.none + " file path " +
" none \n global " + text.bold + text.green + "✓" +
text.none + " none none \n hash " +
" " + text.bold + text.green + "✓" + text.none + " file path " +
" none \n help " + text.bold + text.green + "✓" +
text.none + " number none \n install " +
" " + text.bold + text.yellow + "?" + text.none + " zip file " +
" directory path \n list " + text.bold + text.green + "✓" +
text.none + " \"" + text.yellow + "installed" + text.nocolor +
"\" or \"" + text.yellow + "published" + text.nocolor + "\" none \n" +
" markdown " + text.bold + text.green + "✓" + text.none + " path to" +
" markdown file number \n publish " + text.bold + text.green +
"✓" + text.none + " directory path directory path \n re" +
"move " + text.bold + text.green + "✓" + text.none + " file path or di" +
"rectory path none \n status " + text.bold + text.yellow +
"?" + text.none + " none or application name none \n te" +
"st " + text.bold + text.red + "X" + text.none + " none " +
" none \n uninstall " + text.bold + text.green +
"✓" + text.none + " application name none \n un" +
"publish " + text.bold + text.green + "✓" + text.none + " application nam" +
"e none \n unzip " + text.bold + text.green +
"✓" + text.none + " path to zip file directory path \n zi" +
"p " + text.bold + text.green + "✓" + text.none + " file path or di" +
"rectory path directory path \n\n" + text.underline + text.bold + text.cyan +
"New big Heading" + text.none + "\n paragraph here to see if indentation is la" +
"rg",
name = "biddle_test_markdown_80";
if (er !== null) {
return apps.errout(
{error: er, name: name, stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: name, stdout: stdout, time: humantime(true)}
);
}
stdout = stdout
.replace(/\r\n/g, "\n")
.slice(0, 8192)
.replace(/(\s+)$/, "")
.replace(/(\\(\w+)?\s*)$/, "");
if (stdout !== markdowntest) {
return diffFiles(name, stdout, markdowntest);
}
console.log(
humantime(false) + " " + text.green + "markdown 80 test passed." + text.nocolor
);
flag["80"] = true;
if (flag["60"] === true && flag["120"] === true) {
next();
}
}
);
node.child(
childcmd + "markdown " + data.abspath + "test" + node.path.sep +
"biddletesta" + node.path.sep + "READMEa.md 120 childtest",
{
cwd: data.abspath
},
function biddle_test_markdown_120(er, stdout, stder) {
var markdowntest = "\n" + text.underline + text.bold + text.red + "test README" + text.none + "\ns" +
"ome dummy subtext\n\n" + text.underline + text.bold + text.red + "heading by u" +
"nderline equals" + text.none + "\n\n" + text.underline + text.bold + text.cyan +
"heading by underline dashes" + text.none + "\n\n ===\n\n" + text.underline +
text.bold + text.cyan + "First Secondary Heading" + text.none + "\n | a big " +
"block quote lives here. This is where I am going to experience with wrapping a" +
" block quote a bit\n | differently from other content. I need enough text " +
"in this quote to wrap a couple of times, so I will continue adding\n | some" +
" nonsense and as long as it takes to ensure I have a fully qualified test.\n " +
" | New line in a block quote\n | More block\n\n This is a regular paragra" +
"ph that needs to be long enough to wrap a couple times. This text will be uni" +
"que from the\n text in the block quote because uniqueness saves time when deb" +
"ugging test failures. I am now writing a bunch of\n wrapping paragraph gibbe" +
"rish, such as f324fasdaowkefsdva. That one isn't even a word. It isn't cool " +
"if it\n doesn't contain a hyperlink, (" + text.cyan + "http://tonowhwere.noth" +
"ing" + text.nocolor + "), in some text.\n\n " + text.bold + text.red + "*" +
text.none + " list item 1 these also need to wrap like a paragraph. So blah bla" +
"h wrapping some madness into a list\n item right gosh darn here and let's s" +
"ee what shakes out of the coolness.\n " + text.bold + text.red + "*" + text.none +
" list item 2 these also need to wrap like a paragraph. So blah blah wrapping s" +
"ome madness into a list\n item right gosh darn here and let's see what shak" +
"es out of the coolness.\n " + text.bold + text.red + "-" + text.none + " su" +
"blist item 1 these also need to wrap like a paragraph. So blah blah wrapping s" +
"ome madness into a\n list item right gosh darn here and let's see what sh" +
"akes out of the coolness.\n " + text.bold + text.red + "-" + text.none + " " +
"sublist item 2 these also need to wrap like a paragraph. So blah blah wrapping" +
" some madness into a\n list item right gosh darn here and let's see what " +
"shakes out of the coolness.\n " + text.bold + text.red + "*" + text.none +
" subsublist item 1 these also need to wrap like a paragraph. So blah blah wrap" +
"ping some madness into\n a list item right gosh darn here and let's see" +
" what shakes out of the coolness.\n " + text.bold + text.red + "*" +
text.none + " subsublist item 2 these also need to wrap like a paragraph. So bl" +
"ah blah wrapping some madness into\n a list item right gosh darn here a" +
"nd let's see what shakes out of the coolness.\n " + text.bold + text.red +
"*" + text.none + " list item 3 these also need to wrap like a paragraph. So bl" +
"ah blah wrapping some madness into a list\n item right gosh darn here and l" +
"et's see what shakes out of the coolness.\n " + text.bold + text.red + "-" +
text.none + " boo these also need to wrap like a paragraph. So blah blah wrappi" +
"ng some madness into a list item\n right gosh darn here and let's see wha" +
"t shakes out of the coolness.\n\n " + text.underline + text.bold + text.green +
"First Tertiary Heading #####" + text.none + "\n This text should be extra i" +
"ndented.\n\n " + text.bold + text.red + "*" + text.none + " list item 1\n " +
" " + text.bold + text.red + "*" + text.none + " list item 2\n " + text.bold +
text.red + "-" + text.none + " sublist item 1\n " + text.bold + text.red +
"-" + text.none + " sublist item 2\n " + text.bold + text.red + "*" +
text.none + " subsublist item 1\n " + text.bold + text.red + "*" +
text.none + " subsublist item 2\n " + text.bold + text.red + "*" + text.none +
" list item 3\n " + text.bold + text.red + "-" + text.none +
" boo\n\n " + text.underline + text.bold + text.yellow + "Gettin Deep with t" +
"he Headings" + text.none + "\n\n | a big block quote lives here. This i" +
"s where I am going to experience with wrapping a block quote a bit\n | " +
"differently from other content. I need enough text in this quote to wrap a co" +
"uple of times, so I will continue\n | adding some nonsense and a long a" +
" t takes to ensure I have a fully qualified test.\n | New line in a blo" +
"ck quote\n | More block and not a heading\n | ------------------" +
"------------------------------------------------------------------------------" +
"--------------\n\n | a a a a a a a a a a a a a a a a a a a a a a a a a " +
"a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a\n | a a a a" +
" a a a a a a a a a a a a a\n\n | aa a a a a a a a a a a a a a a a a a a" +
" a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a\n " +
" | a a a a a a a a a a a a a a a a a a\n\n Horizontal Rule with *\n*****" +
"******************************************************************************" +
"*************************************\n\n Horizontal Rule with - (require" +
"s an empty line between it and text)\n\n--------------------------------------" +
"------------------------------------------------------------------------------" +
"----\n\n Horizontal Rule with _\n________________________________________" +
"______________________________________________________________________________" +
"__\n\n Images get converted to their alt text description.\n\n This " +
"is a regular paragraph that needs to be long enough to wrap a couple times. T" +
"his text will be unique from the\n text in the block quote because unique" +
"ness saves time when debugging test failures. I am now writing a\n bunch" +
" of wrapping paragraph gibberish, such as f324fasdaowkefsdva. That one isn't " +
"even a word.\n\n " + text.bold + text.red + "*" + text.none + " list item" +
" 1 these also need to wrap like a paragraph. So blah blah wrapping some madnes" +
"s into a list\n item right gosh darn here and let's see what shakes out" +
" of the coolness.\n " + text.bold + text.red + "*" + text.none + " list i" +
"tem 2 these also need to wrap like a paragraph. So blah blah wrapping some mad" +
"ness into a list\n item right gosh darn here and let's see what shakes " +
"out of the coolness.\n " + text.bold + text.red + "-" + text.none + " s" +
"ublist item 1 these also need to wrap like a paragraph. So blah blah wrapping " +
"some madness into a\n list item right gosh darn here and let's see wh" +
"at shakes out of the coolness.\n " + text.bold + text.red + "-" +
text.none + " sublist item 2 these also need to wrap like a paragraph. So blah " +
"blah wrapping some madness into a\n list item right gosh darn here an" +
"d let's see what shakes out of the coolness.\n " + text.bold + text.red +
"*" + text.none + " subsublist item 1 these also need to wrap like a paragraph." +
" So blah blah wrapping some madness\n into a list item right gosh d" +
"arn here and let's see what shakes out of the coolness.\n " + text.bold +
text.red + "*" + text.none + " subsublist item 2 these also need to wrap like a" +
" paragraph. So blah blah wrapping some madness\n into a list item r" +
"ight gosh darn here and let's see what shakes out of the coolness.\n " +
text.bold + text.red + "*" + text.none + " list item 3 these also need to wrap " +
"like a paragraph. So blah blah wrapping some madness into a list\n item" +
" right gosh darn here and let's see what shakes out of the coolness.\n " +
text.bold + text.red + "-" + text.none + " boo these also need to wrap like a p" +
"aragraph. So blah blah wrapping some madness into a list item\n right" +
" gosh darn here and let's see what shakes out of the coolness.\n\n " +
text.underline + "Command " + text.normal + text.underline + " Local " +
text.normal + text.underline + " Argument Type " + text.normal +
text.underline + " Second Argument " + text.normal + "\n copy " +
text.bold + text.green + "✓" + text.none + " file path or directory path " +
"directory path \n get " + text.bold + text.yellow + "?" + text.none +
" file path none \n global " +
text.bold + text.green + "✓" + text.none + " none " +
"none \n hash " + text.bold + text.green + "✓" + text.none +
" file path none \n help " +
text.bold + text.green + "✓" + text.none + " number " +
"none \n install " + text.bold + text.yellow + "?" + text.none +
" zip file directory path \n list " +
text.bold + text.green + "✓" + text.none + " \"" + text.yellow +
"installed" + text.nocolor + "\" or \"" + text.yellow + "published" + text.nocolor +
"\" none \n markdown " + text.bold + text.green + "✓" +
text.none + " path to markdown file number \n publish " +
" " + text.bold + text.green + "✓" + text.none + " directory path " +
" directory path \n remove " + text.bold + text.green + "✓" +
text.none + " file path or directory path none \n status " +
" " + text.bold + text.yellow + "?" + text.none + " none or application " +
"name none \n test " + text.bold + text.red + "X" +
text.none + " none none \n uninstal" +
"l " + text.bold + text.green + "✓" + text.none + " application name " +
" none \n unpublish " + text.bold + text.green + "✓" +
text.none + " application name none \n unzip " +
" " + text.bold + text.green + "✓" + text.none + " path to zip file " +
" directory path \n zip " + text.bold + text.green + "✓" +
text.none + " file path or directory path directory path \n\n" + text.underline +
text.bold + text.cyan + "New big Heading" + text.none + "\n paragraph here to " +
"see if indentation is largely reset appropriate to the cu",
name = "biddle_test_markdown_120";
if (er !== null) {
return apps.errout(
{error: er, name: name, stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: name, stdout: stdout, time: humantime(true)}
);
}
stdout = stdout
.replace(/\r\n/g, "\n")
.slice(0, 8192)
.replace(/(\s+)$/, "")
.replace(/(\\(\w+)?)$/, "");
if (stdout !== markdowntest) {
return diffFiles(name, stdout, markdowntest);
}
console.log(
humantime(false) + " " + text.green + "mmarkdown 120 test passed." + text.nocolor
);
flag["120"] = true;
if (flag["60"] === true && flag["80"] === true) {
next();
}
}
);
};
phases.moduleInstall = function biddle_test_moduleInstall() {
var dateobj = new Date(),
day = (dateobj.getDate() > 9)
? "" + dateobj.getDate()
: "0" + dateobj.getDate(),
month = (dateobj.getMonth() > 8)
? "" + (
dateobj.getMonth() + 1
)
: "0" + (
dateobj.getMonth() + 1
),
date = Number("" + dateobj.getFullYear() + month + day),
ind = 0,
today = require(data.abspath + "today.js"),
intpath = __dirname + node.path.sep + "internal" + node.path.sep,
modules = {
jslint : "http://prettydiff.com/downloads/jslint/jslint_latest.zip",
prettydiff: "http://prettydiff.com/downloads/prettydiff/prettydiff_cli_latest.zip"
},
versions = {},
inst = 0,
newinstall = false,
keys = Object.keys(modules),
complete = function biddle_test_moduleInstall_complete() {
var verkeys = Object.keys(versions),
len = verkeys.length,
a = 0,
longname = (function biddle_test_moduleInstall_complete_longname() {
var aa = 0,
long = 0;
do {
if (verkeys[aa].length > long) {
long = verkeys[aa].length;
}
aa = aa + 1;
} while (aa < len);
return long;
}()),
namepad = function biddle_test_namepad(name) {
var aa = name.length;
if (name.length === longname) {
return name;
}
do {
aa = aa + 1;
name = name + " ";
} while (aa < longname);
return name;
};
verkeys.sort();
console.log("Installed module versions");
console.log("-------------------------");
do {
console.log(
"* " + text.bold + text.cyan + namepad(verkeys[a]) + text.none + " - " + text.bold +
text.green + versions[verkeys[a]] + text.none
);
a = a + 1;
} while (a < len);
next();
},
writeToday = function biddle_test_moduleInstall_writeToday() {
node
.fs
.writeFile(
data.abspath + "today.js",
"/\u002aglobal module\u002a/(function () {\"use strict\";var today=" + date + ";module.exports=today;}());",
function biddle_test_moduleInstall_writeToday_writeFile(werr) {
if (werr !== null && werr !== undefined) {
return apps.errout(
{error: werr, name: "biddle_test_moduleInstall_writeToday_writeFile", time: humantime(true)}
);
}
complete();
}
);
},
modcheck = function biddle_test_moduleInstall_modcheck(mod) {
var modinstall = function biddle_test_moduleInstall_modcheck_modinstall() {
apps.install(
modules[mod],
function biddle_test_moduleInstall_modcheck_modinstall_install(packjson) {
newinstall = true;
mods[mod] = require(intpath + mod + node.path.sep + packjson.main);
versions[mod] = packjson.version;
inst = inst + 1;
if (inst === keys.length) {
writeToday();
}
}
);
},
modrequire = function biddle_test_moduleInstall_modrequire() {
node
.fs
.readFile(
intpath + mod + node.path.sep + "package.json",
"utf8",
function biddle_test_moduleInstall_modrequire_readFile(packer, packjson) {
var json = {};
if (packer !== null) {
return apps.errout(
{error: packer, name: "biddle_test_moduleInstall_modrequire_readFile", stdout: packjson, time: humantime(true)}
);
}
json = JSON.parse(packjson);
versions[mod] = json.version;
mods[mod] = require(intpath + mod + node.path.sep + json.main);
inst = inst + 1;
if (inst === keys.length) {
if (newinstall === true) {
writeToday();
} else {
complete();
}
}
}
);
};
node
.fs
.stat(
intpath + mod + node.path.sep + "package.json",
function biddle_test_moduleInstall_modcheck_stat(erstat, stats) {
if (erstat === null && stats.isFile() === true && data.installed.internal !== undefined && data.installed.internal[mod] !== undefined) {
if (date > today) {
apps.update(mod, true, modrequire);
} else {
modrequire();
}
} else {
modinstall();
}
}
);
};
if (date > today) {
newinstall = true;
}
do {
modcheck(keys[ind]);
ind = ind + 1;
} while (ind < keys.length);
};
phases.publishA = function biddle_test_publishA() {
phasenumb = phasenumb + 1;
console.log(
phasenumb + ". First set of publish tests"
);
node.child(
childcmd + "publish " + data.abspath + "test" + node.path.sep + "biddletesta ch" +
"ildtest",
{
cwd: data.abspath
},
function biddle_test_publishA_child(er, stdout, stder) {
var bgreen = text.bold + text.green,
bcyan = text.bold + text.cyan,
publishtest = "File publications/biddletesta/biddlesort.js written at " +
bgreen + "xxx" + text.none + " bytes.\nFile publications/biddletesta/biddletest" +
"a_" + bcyan + "xxx.zip" + text.none + " written at " + bgreen + "xxx" + text.none +
" bytes.\nFile publications/biddletesta/biddletesta_" + bcyan + "latest.zip" +
text.none + " written at " + bgreen + "xxx" + text.none + " bytes.\nFile public" +
"ations/biddletesta/biddletesta_" + bcyan + "min_xxx.zip" + text.none + " writt" +
"en at " + bgreen + "xxx" + text.none + " bytes.\nFile publications/biddletesta" +
"/biddletesta_" + bcyan + "min_latest.zip" + text.none + " written at " +
bgreen + "xxx" + text.none + " bytes.\nFile publications/biddletesta/biddletest" +
"a_" + bcyan + "prod_xxx.zip" + text.none + " written at " + bgreen + "xxx" +
text.none + " bytes.\nFile publications/biddletesta/biddletesta_" + bcyan + "pr" +
"od_latest.zip" + text.none + " written at " + bgreen + "xxx" + text.none + " b" +
"ytes.\nFile publications/biddletesta/filedata.json written at " + bgreen +
"xxx" + text.none + " bytes.\nFile publications/biddletesta/index.xhtml written" +
" at " + bgreen + "xxx" + text.none + " bytes.\nFile publications/biddletesta/l" +
"atest.txt written at " + bgreen + "xxx" + text.none + " bytes.",
outputs = stdout
.replace(/(\s+)$/, "")
.replace("\r\n", "\n")
.split("\n")
.sort(function biddle_test_publishA_child_outSort(a, b) {
if (a > b) {
return 1;
}
return -1;
}),
output = "",
abspath = new RegExp(data.abspath.replace(/\\/g, "\\\\"), "g");
if (er !== null) {
apps.errout(
{error: er, name: "biddle_test_publishA_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
apps.errout(
{error: stder, name: "biddle_test_publishA_child", stdout: stdout, time: humantime(true)}
);
}
node
.fs
.stat(
data.abspath + "temp",
function biddle_test_publishA_child_statTemp(errtemp) {
if (errtemp === null) {
return apps.errout(
{error: "Failed to remove directory 'temp' from publish operation.", name: "biddle_test_publishA_child_statTemp", stdout: stdout, time: humantime(true)}
);
}
if (errtemp.toString().indexOf("no such file or directory") < 0) {
return apps.errout(
{error: errtemp, name: "biddle_test_publishA_child_statTemp", stdout: stdout, time: humantime(true)}
);
}
outputs.forEach(
function biddle_test_publishA_child_statTemp_formatOutput(value, index, array) {
var val = value.slice(value.indexOf("publications"));
array[index] = "File " + val;
}
);
output = outputs.join("\n");
output = output.replace(/\\/g, "/");
output = output
.replace(/\d+\.\d+\.\d+\.zip/g, "xxx.zip")
.replace(/\u001b\[32m\d+(,\d+)*/g, text.green + "xxx")
.replace(abspath, "");
if (stdout.indexOf("Error") > 0) {
console.log(stdout);
return apps.errout(
{error: "Error from child process", name: "biddle_test_publishA_child_statTemp", stdout: stdout, time: humantime(true)}
);
}
if (output !== publishtest) {
return diffFiles("biddle_test_publishA_child_statTemp", output, publishtest);
}
console.log(
humantime(false) + " " + text.green + "The stdout for publish is correct." +
text.nocolor
);
node
.fs
.readFile(
data.abspath + "published.json",
"utf8",
function biddle_test_publishA_child_statTemp_readJSON(err, fileData) {
var jsondata = {},
pub = data.abspath + "publications" + node.path.sep + "biddletesta";
if (err !== null && err !== undefined) {
return apps.errout(
{error: err, name: "biddle_test_publishA_child_statTemp_readJSON", stdout: stdout, time: humantime(true)}
);
}
jsondata = JSON.parse(fileData);
if (jsondata.biddletesta === undefined) {
return apps.errout(
{error: "No biddletesta property in published.json file.", name: "biddle_test_publishA_child_statTemp_readJSON", stdout: stdout, time: humantime(true)}
);
}
if ((/^(99\.99\.\d{4})$/).test(jsondata.biddletesta.latest) === false) {
return apps.errout({
error : "biddletesta.latest of published.json is '" + jsondata.biddletesta.latest + "' " +
"not equivalent to '99\\.99\\.\\d{4}'.",
name : "biddle_test_publishA_child_statTemp_readJSON",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green +
"File published.json contains biddletesta" + text.nocolor
);
node
.fs
.readdir(
pub,
function biddle_test_publishA_child_statTemp_readJSON_readdir(errr, files) {
var filetest = "biddlesort.js,biddletesta_v.hash,biddletesta_v.zip,biddletesta_latest.hash,bid" +
"dletesta_latest.zip,biddletesta_min_v.hash,biddletesta_min_v.zip,biddletesta_m" +
"in_latest.hash,biddletesta_min_latest.zip,biddletesta_prod_v.hash,biddletesta_" +
"prod_v.zip,biddletesta_prod_latest.hash,biddletesta_prod_latest.zip,filedata.j" +
"son,index.xhtml,latest.txt",
filelist = files
.sort(
function biddle_test_publishA_child_statTemp_readJSON_readdir_outSort(a, b) {
if (a > b) {
return 1;
}
return -1;
}
)
.join(",")
.replace(
/_\d+\.\d+\.\d+\.((zip)|(hash))/g,
function biddle_test_publishA_child_statTemp_readJSON_readdir_replace(x) {
if (x.indexOf("zip") > 0) {
return "_v.zip";
}
return "_v.hash";
}
),
stats = {},
statfile = function biddle_test_publishA_child_statTemp_readJSON_readdir_statfile(
index
) {
stats[files[index]] = false;
node
.fs
.stat(
pub + node.path.sep + files[index],
function biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback(errs, statobj) {
if (errs !== null) {
return apps.errout(
{error: errs, name: "biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback", stdout: stdout, time: humantime(true)}
);
}
if (files[index].indexOf(".hash") === files[index].length - 5 && statobj.size !== 128) {
return apps.errout({
error : "Expected hash file " + files[index] + " to be file size 128.",
name : "biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback",
stdout: stdout,
time : humantime(true)
});
}
if (files[index].indexOf(".zip") === files[index].length - 4 && statobj.size > 20000) {
return apps.errout({
error : "Zip file " + files[index] + " is too big at " + apps.commas(
statobj.size
) + ".",
name : "biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + files[index] + " present at size " + text.bold +
text.green + apps.commas(statobj.size) + text.none + " bytes."
);
stats[files[index]] = true;
if (stats[files[0]] === true && stats[files[1]] === true && stats[files[2]] === true && stats[files[3]] === true && stats[files[4]] === true && stats[files[5]] === true && stats[files[6]] === true && stats[files[7]] === true && stats[files[8]] === true && stats[files[9]] === true && stats[files[10]] === true && stats[files[11]] === true) {
console.log(
humantime(false) + " " + text.green + "publish test passed." + text.nocolor
);
node.child(
childcmd + "publish " + data.abspath + "test" + node.path.sep + "biddletesta ch" +
"ildtest",
{
cwd: data.abspath
},
function biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback_publish(erx, stdoutx, stderx) {
var publishagain = text.bold + text.cyan + "Function:" + text.none + " biddle_p" +
"ublish_execution\n" + text.bold + text.red + "Error:" + text.none + " Attempte" +
"d to publish biddletesta over existing version",
stack = [];
if (erx !== null) {
if (typeof erx.stack === "string") {
stack = erx
.stack
.split(" at ");
}
if (stack.length < 1 || stack[1].indexOf("ChildProcess.exithandler (child_process.js:2") < 0) {
return apps.errout(
{error: erx, name: "biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback_publish", stdout: stdout, time: humantime(true)}
);
}
}
if (stderx !== null && stderx !== "") {
return apps.errout(
{error: stderx, name: "biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback_publish", stdout: stdout, time: humantime(true)}
);
}
stdoutx = stdoutx
.replace("\r\n", "\n")
.replace(/(\u0020\d+\.\d+\.\d+\s*)$/, "")
.slice(0, stdoutx.indexOf(" version") + 8);
if (stdoutx !== publishagain) {
return diffFiles(
"biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback_publish",
stdoutx,
publishagain
);
}
node
.fs
.stat(
data.abspath + "temp",
function biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback_publish_statTemp(errtemp) {
if (errtemp === null) {
return apps.errout({
error: "Failed to remove directory 'temp' from publish operation.",
name : "biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback_publish" +
"_statTemp",
time : humantime(true)
});
}
if (errtemp.toString().indexOf("no such file or directory") < 0) {
return apps.errout({
error: errtemp,
name : "biddle_test_publishA_child_statTemp_readJSON_readdir_statfile_statback_publish" +
"_statTemp",
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + "Redundant publish test (error messaging)" +
" passed." + text.nocolor
);
next();
}
);
}
);
}
}
);
};
if (errr !== null) {
return apps.errout(
{error: errr, name: "biddle_test_publishA_child_statTemp_readJSON_readdir", stdout: stdout, time: humantime(true)}
);
}
if (filelist !== filetest) {
return diffFiles(
"biddle_test_publishA_child_statTemp_readJSON_readdir",
filelist,
filetest
);
}
console.log(
humantime(false) + " " + text.green + "List of files generated by publish is co" +
"rrect." + text.nocolor
);
statfile(0);
statfile(1);
statfile(2);
statfile(3);
statfile(4);
statfile(5);
statfile(6);
statfile(7);
statfile(8);
statfile(9);
statfile(10);
statfile(11);
}
);
return stdout;
}
);
}
);
}
);
};
phases.publishB = function biddle_test_publishB() {
phasenumb = phasenumb + 1;
console.log(
phasenumb + ". Second set of publish tests"
);
node.child(
childcmd + "publish " + data.abspath + "test" + node.path.sep + "biddletestb ch" +
"ildtest",
{
cwd: data.abspath
},
function biddle_test_publishB_child(er, stdout, stder) {
var bgreen = text.bold + text.green,
bcyan = text.bold + text.cyan,
publishtest = "File publications/biddletestb/biddlesort.js written at " +
bgreen + "xxx" + text.none + " bytes.\nFile publications/biddletestb/biddletest" +
"b_" + bcyan + "xxx.zip" + text.none + " written at " + bgreen + "xxx" + text.none +
" bytes.\nFile publications/biddletestb/biddletestb_" + bcyan + "latest.zip" +
text.none + " written at " + bgreen + "xxx" + text.none + " bytes.\nFile public" +
"ations/biddletestb/biddletestb_" + bcyan + "min_xxx.zip" + text.none + " writt" +
"en at " + bgreen + "xxx" + text.none + " bytes.\nFile publications/biddletestb" +
"/biddletestb_" + bcyan + "min_latest.zip" + text.none + " written at " +
bgreen + "xxx" + text.none + " bytes.\nFile publications/biddletestb/biddletest" +
"b_" + bcyan + "prod_xxx.zip" + text.none + " written at " + bgreen + "xxx" +
text.none + " bytes.\nFile publications/biddletestb/biddletestb_" + bcyan + "pr" +
"od_latest.zip" + text.none + " written at " + bgreen + "xxx" + text.none + " b" +
"ytes.\nFile publications/biddletestb/filedata.json written at " + bgreen +
"xxx" + text.none + " bytes.\nFile publications/biddletestb/index.xhtml written" +
" at " + bgreen + "xxx" + text.none + " bytes.\nFile publications/biddletestb/l" +
"atest.txt written at " + bgreen + "xxx" + text.none + " bytes.",
outputs = stdout
.replace(/(\s+)$/, "")
.replace("\r\n", "\n")
.split("\n")
.sort(function biddle_test_publishB_child_outSort(a, b) {
if (a > b) {
return 1;
}
return -1;
}),
output = "",
abspath = new RegExp(data.abspath.replace(/\\/g, "\\\\"), "g");
if (er !== null) {
apps.errout(
{error: er, name: "biddle_test_publishA_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
apps.errout(
{error: stder, name: "biddle_test_publishA_child", stdout: stdout, time: humantime(true)}
);
}
node
.fs
.stat(
data.abspath + "temp",
function biddle_test_publishB_child_statTemp(errtemp) {
if (errtemp === null) {
return apps.errout(
{error: "Failed to remove directory 'temp' from publish operation.", name: "biddle_test_publishB_child_statTemp", stdout: stdout, time: humantime(true)}
);
}
if (errtemp.toString().indexOf("no such file or directory") < 0) {
return apps.errout(
{error: errtemp, name: "biddle_test_publishB_child_statTemp", stdout: stdout, time: humantime(true)}
);
}
outputs.forEach(
function biddle_test_publishB_child_statTemp_formatOutput(value, index, array) {
var val = value.slice(value.indexOf("publications"));
array[index] = "File " + val;
}
);
output = outputs.join("\n");
output = output.replace(/\\/g, "/");
output = output
.replace(/\d+\.\d+\.\d+\.zip/g, "xxx.zip")
.replace(/(\u001b\[32m\d+(,\d+)*)/g, text.green + "xxx")
.replace(abspath, "");
if (stdout.indexOf("Error") > 0) {
console.log(stdout);
return apps.errout(
{error: "Error from child process", name: "biddle_test_publishB_child_statTemp", stdout: stdout, time: humantime(true)}
);
}
if (output !== publishtest) {
return diffFiles("biddle_test_publishB_child_statTemp", output, publishtest);
}
console.log(
humantime(false) + " " + text.green + "The stdout for publish is correct." +
text.nocolor
);
node
.fs
.readFile(
data.abspath + "published.json",
"utf8",
function biddle_test_publishB_child_statTemp_readJSON(err, fileData) {
var jsondata = {},
pub = data.abspath + "unittest" + node.path.sep + "publications" + node.path.sep +
"biddletestb";
if (err !== null && err !== undefined) {
return apps.errout(
{error: err, name: "biddle_test_publishB_child_statTemp_readJSON", stdout: stdout, time: humantime(true)}
);
}
jsondata = JSON.parse(fileData);
if (jsondata.biddletestb === undefined) {
return apps.errout(
{error: "No biddletestb property in published.json file.", name: "biddle_test_publishB_child_statTemp_readJSON", stdout: stdout, time: humantime(true)}
);
}
if (jsondata.biddletestb.latest !== "98.98.1234") {
return apps.errout({
error : "biddletestb.latest of published.json is '" + jsondata.biddletestb.latest + "' " +
"not 98.98.1234'.",
name : "biddle_test_publishB_child_statTemp_readJSON",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green +
"File published.json contains biddletestb" + text.nocolor
);
node
.fs
.readdir(
pub,
function biddle_test_publishB_child_statTemp_readJSON_readdir(errr, files) {
var filetest = "biddlesort.js,biddletestb_v.hash,biddletestb_v.zip,biddletestb_latest.hash,bid" +
"dletestb_latest.zip,biddletestb_min_v.hash,biddletestb_min_v.zip,biddletestb_m" +
"in_latest.hash,biddletestb_min_latest.zip,biddletestb_prod_v.hash,biddletestb_" +
"prod_v.zip,biddletestb_prod_latest.hash,biddletestb_prod_latest.zip,filedata.j" +
"son,index.xhtml,latest.txt",
filelist = files
.sort(
function biddle_test_publishB_child_statTemp_readJSON_readdir_outSort(a, b) {
if (a > b) {
return 1;
}
return -1;
}
)
.join(",")
.replace(
/_\d+\.\d+\.\d+\.((zip)|(hash))/g,
function biddle_test_publishB_child_statTemp_readJSON_readdir_replace(x) {
if (x.indexOf("zip") > 0) {
return "_v.zip";
}
return "_v.hash";
}
),
stats = {},
statfile = function biddle_test_publishB_child_statTemp_readJSON_readdir_statfile(
index
) {
stats[files[index]] = false;
node
.fs
.stat(
pub + node.path.sep + files[index],
function biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback(errs, statobj) {
if (errs !== null) {
return apps.errout(
{error: errs, name: "biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback", stdout: stdout, time: humantime(true)}
);
}
if (files[index].indexOf(".hash") === files[index].length - 5 && statobj.size !== 128) {
return apps.errout({
error : "Expected hash file " + files[index] + " to be file size 128.",
name : "biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback",
stdout: stdout,
time : humantime(true)
});
}
if (files[index].indexOf(".zip") === files[index].length - 4 && statobj.size > 20000) {
return apps.errout({
error : "Zip file " + files[index] + " is too big at " + apps.commas(
statobj.size
) + ".",
name : "biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + files[index] + " present at size " + text.bold +
text.green + apps.commas(statobj.size) + text.none + " bytes."
);
stats[files[index]] = true;
if (stats[files[0]] === true && stats[files[1]] === true && stats[files[2]] === true && stats[files[3]] === true && stats[files[4]] === true && stats[files[5]] === true && stats[files[6]] === true && stats[files[7]] === true && stats[files[8]] === true && stats[files[9]] === true && stats[files[10]] === true && stats[files[11]] === true) {
console.log(
humantime(false) + " " + text.green + "publish test passed." + text.nocolor
);
node.child(
childcmd + "publish " + data.abspath + "test" + node.path.sep + "biddletestb ch" +
"ildtest",
{
cwd: data.abspath
},
function biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback_publish(erx, stdoutx, stderx) {
var publishagain = text.bold + text.cyan + "Function:" + text.none + " biddle_p" +
"ublish_execution\n" + text.bold + text.red + "Error:" + text.none + " Attempte" +
"d to publish biddletestb over existing version",
stack = [];
if (erx !== null) {
if (typeof erx.stack === "string") {
stack = erx
.stack
.split(" at ");
}
if (stack.length < 1 || stack[1].indexOf("ChildProcess.exithandler (child_process.js:2") < 0) {
return apps.errout(
{error: erx, name: "biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback_publish", stdout: stdout, time: humantime(true)}
);
}
}
if (stderx !== null && stderx !== "") {
return apps.errout(
{error: stderx, name: "biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback_publish", stdout: stdout, time: humantime(true)}
);
}
stdoutx = stdoutx
.replace("\r\n", "\n")
.replace(/(\u0020\d+\.\d+\.\d+\s*)$/, "")
.slice(0, stdoutx.indexOf(" version") + 8);
if (stdoutx !== publishagain) {
return diffFiles(
"biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback_publish",
stdoutx,
publishagain
);
}
node
.fs
.stat(
data.abspath + "temp",
function biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback_publish_statTemp(errtemp) {
if (errtemp === null) {
return apps.errout({
error: "Failed to remove directory 'temp' from publish operation.",
name : "biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback_publish" +
"_statTemp",
time : humantime(true)
});
}
if (errtemp.toString().indexOf("no such file or directory") < 0) {
return apps.errout({
error: errtemp,
name : "biddle_test_publishB_child_statTemp_readJSON_readdir_statfile_statback_publish" +
"_statTemp",
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + "Redundant publish test (error messaging)" +
" passed." + text.nocolor
);
next();
}
);
}
);
}
}
);
};
if (errr !== null) {
return apps.errout(
{error: errr, name: "biddle_test_publishB_child_statTemp_readJSON_readdir", stdout: stdout, time: humantime(true)}
);
}
if (filelist !== filetest) {
return diffFiles(
"biddle_test_publishB_child_statTemp_readJSON_readdir",
filelist,
filetest
);
}
console.log(
humantime(false) + " " + text.green + "List of files generated by publish is co" +
"rrect." + text.nocolor
);
statfile(0);
statfile(1);
statfile(2);
statfile(3);
statfile(4);
statfile(5);
statfile(6);
statfile(7);
statfile(8);
statfile(9);
statfile(10);
statfile(11);
}
);
return stdout;
}
);
}
);
}
);
};
phases.remove = function biddle_test_remove() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Remove tests");
node.child(
childcmd + "remove " + testpath + node.path.sep + "biddletesta.js childtest",
{
cwd: data.abspath
},
function biddle_test_remove_child(er, stdout, stder) {
var removefile = testpath + node.path.sep + "biddletesta.js",
removetest = "biddle removed " + text.red + text.bold + "0" + text.none + " dir" +
"ectories, " + text.red + text.bold + "1" + text.none + " files, " + text.red +
text.bold + "0" + text.none + " symbolic links, and " + text.red + text.bold +
"0" + text.none + " other types at " + text.red + text.bold + "23,177" + text.none +
" bytes.\nRemoved " + text.cyan + removefile + text.nocolor;
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_remove_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_remove_child", stdout: stdout, time: humantime(true)}
);
}
stdout = stdout.replace(/(\s+)$/, "");
if (stdout !== removetest) {
return diffFiles("biddle_test_remove_child", stdout, removetest);
}
node
.fs
.stat(removefile, function biddle_test_remove_child_stat(ers) {
if (ers === null || ers.toString().indexOf("no such file for directory") > 0) {
return apps.errout(
{error: "remove test failed as file is still present", name: "biddle_test_remove_child_stat", stdout: stdout, time: humantime(true)}
);
}
console.log(
humantime(false) + " " + text.green + "remove test passed." + text.nocolor
);
next();
});
}
);
};
phases.republish = function biddle_test_republish() {
var packpath = data.abspath + "test" + node.path.sep + "biddletesta" + node.path.sep + "pac" +
"kage.json";
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Republish tests");
node
.fs
.readFile(packpath, function biddle_test_republish_read(rfer, packjson) {
var pack = JSON.parse(packjson),
ver = pack
.version
.split(".");
if (rfer !== null) {
return apps.errout(
{error: rfer, name: "biddle_test_republish_read", stdout: "", time: humantime(true)}
);
}
if (ver[ver.length - 1] === "9999") {
ver[ver.length - 1] = "0000";
} else {
ver[ver.length - 1] = String(Number(ver[ver.length - 1]) + 1);
}
pack.version = ver.join(".");
apps.writeFile(
JSON.stringify(pack),
packpath,
function biddle_test_republish_read_write() {
var pubdirs = data
.abspath
.split(node.path.sep);
pubdirs.pop();
console.log(
humantime(false) + " " + text.green + "version updated for test" + node.path.sep +
"biddletesta to:" + text.nocolor + " 99.99." + ver[ver.length - 1]
);
node.child(childcmd + "publish " + packpath.replace(
node.path.sep + "package.json",
""
), {
cwd: pubdirs.join(node.path.sep)
}, function biddle_test_republish_read_write_publish(er, stdout, stder) {
var flag = {
index : false,
publish: false,
rdirs : false
},
complete = function () {
var fkeys = Object.keys(flag),
a = fkeys.length - 1;
do {
if (flag[fkeys[a]] === false) {
return;
}
a = a - 1;
} while (a > -1);
next();
};
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_republish_read_write_publish", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_republish_read_write_publish", stdout: stdout, time: humantime(true)}
);
}
node
.fs
.readdir(
data.abspath + "publications" + node.path.sep + "biddletesta",
function biddle_test_republish_read_write_publish_readDir(der, files) {
if (der !== null) {
return apps.errout(
{error: der, name: "biddle_test_republish_read_write_publish_readDir", stdout: stdout, time: humantime(true)}
);
}
if (files.length !== 22) {
return apps.errout({
error : "Expected 22 files in the published directory, but instead there are " +
files.length + "\r\n* " + files.join("\r\n* "),
name : "biddle_test_republish_read_write_publish_readDir",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + "20 files in publications" + node.path.sep +
"biddletesta" + text.nocolor
);
flag.rdirs = true;
complete();
}
);
node
.fs
.readFile(
data.abspath + "publications" + node.path.sep + "biddletesta" + node.path.sep +
"index.xhtml",
function biddle_test_republish_read_write_publish_readIndex(ier, file) {
var index = "",
trs = [];
if (ier !== null) {
return apps.errout(
{error: ier, name: "biddle_test_republish_read_write_publish_readIndex", stdout: stdout, time: humantime(true)}
);
}
index = (typeof file === "string")
? file
: file.toString();
index = index.replace(/99\.99\.\d{4}/g, "99.99.xxxx");
trs = index.split("99.99.xxxx | ");
if (trs.length !== 10) {
return apps.errout({
error : "Expected 9 zip files in index.xhtml, but there are " + (
trs.length - 1
),
name : "biddle_test_republish_read_write_publish_readIndex",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + "9 entries in publications" + node.path.sep +
"biddletesta" + node.path.sep + "index.xhtml" + text.nocolor
);
flag.index = true;
complete();
}
);
node
.fs
.readFile(
data.abspath + "published.json",
function biddle_test_republish_read_write_publish_readPublished(per, file) {
var pub = {};
if (per !== null) {
return apps.errout(
{error: per, name: "biddle_test_republish_read_write_publish_readPublished", stdout: stdout, time: humantime(true)}
);
}
pub = JSON.parse(file);
if (pub.biddletesta.versions.length !== 2) {
return apps.errout({
error : "Expected (published.json).biddletesta.versions of published.json to have two v" +
"ersion numbers",
name : "biddle_test_republish_read_write_publish_readPublished",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + "(published.json).biddletesta.versions ha" +
"s two version numbers" + text.nocolor
);
if (pub.biddletesta.directory !== data.abspath + "publications" + node.path.sep + "biddletesta" + node.path.sep) {
return diffFiles(
"biddle_test_republish_read_write_publish_readPublished",
pub.biddletesta.directory,
data.abspath + "publications" + node.path.sep + "biddletesta/"
);
}
console.log(
humantime(false) + " " + text.green + "(published.json).biddletesta.directory i" +
"s correct location" + text.nocolor
);
flag.publish = true;
complete();
}
);
});
}
);
});
};
phases.uninstall = function biddle_test_uninstall() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Uninstall tests");
node.child(
childcmd + "uninstall biddletesta childtest",
{
cwd: data.abspath
},
function biddle_test_uninstall_child(er, stdout, stder) {
var uninsttest = "App " + text.cyan + "biddletesta" + text.nocolor + " is unins" +
"talled.";
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_uninstall_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_uninstall_child", stdout: stdout, time: humantime(true)}
);
}
stdout = stdout.replace(/(\s+)$/, "");
if (stdout !== uninsttest) {
return diffFiles("biddle_test_uninstall_child", stdout, uninsttest);
}
if (data.installed.biddletesta !== undefined) {
return apps.errout(
{error: "biddletesta property not removed from data.installed object", name: "biddle_test_uninstall_child", stdout: stdout, time: humantime(true)}
);
}
console.log(
humantime(false) + " " + text.green +
"biddletesta removed from installed.json." + text.nocolor
);
node
.fs
.stat(
data.abspath + "applications" + node.path.sep + "biddletesta",
function biddle_test_uninstall_child_stat(err, stat) {
if (err !== null && err.toString().indexOf("no such file or directory") < 0) {
return apps.errout(
{error: err, name: "biddle_test_uninstall_child_stat", time: humantime(true)}
);
}
if (stat !== undefined && stat.isDirectory() === true) {
return apps.errout({
error : "applications" + node.path.sep + "biddletesta directory not deleted by uninstal" +
"l command",
name : "biddle_test_uninstall_child_stat",
stdout: stdout,
time : humantime(true)
});
}
if (err.toString().indexOf("no such file or directory") > 0) {
node
.fs
.readFile(
data.abspath + "installed.json",
function biddle_test_uninstall_child_stat_readfile(erf, filedata) {
var jsondata = {};
if (erf !== null && erf !== undefined) {
return apps.errout(
{error: erf, name: "biddle_test_uninstall_child_stat_readfile", stdout: stdout, time: humantime(true)}
);
}
jsondata = JSON.parse(filedata);
if (jsondata.biddletesta !== undefined) {
return apps.errout(
{error: "biddletesta property still present in installed.json file", name: "biddle_test_uninstall_child_stat_readfile", stdout: stdout, time: humantime(true)}
);
}
console.log(
humantime(false) + " " + text.green + "uninstall test passed." + text.nocolor
);
node.child(
childcmd + "uninstall biddletesta childtest",
{
cwd: data.abspath
},
function biddle_test_uninstall_child_stat_readfile_again(erx, stdoutx, stderx) {
var uninstagain = "Attempted to uninstall " + text.cyan + "biddletesta" +
text.nocolor + " which is " + text.bold + text.red + "absent" + text.none + " f" +
"rom the list of installed applications. Try using the command " + text.green +
"biddle list installed" + text.nocolor + ".",
stack = [];
if (erx !== null) {
if (typeof erx.stack === "string") {
stack = erx
.stack
.split(" at ");
}
if (stack.length < 1 || stack[1].indexOf("ChildProcess.exithandler (child_process.js:202:12)") < 0) {
return apps.errout(
{error: erx, name: "biddle_test_uninstall_child_stat_readfile_again", stdout: stdout, time: humantime(true)}
);
}
}
if (stderx !== null && stderx !== "") {
return apps.errout(
{error: stderx, name: "biddle_test_uninstall_child_stat_readfile_again", stdout: stdout, time: humantime(true)}
);
}
stdoutx = stdoutx.replace(/(\s+)$/, "");
if (stdoutx !== uninstagain) {
return diffFiles(
"biddle_test_uninstall_child_stat_readfile_again",
stdoutx,
uninstagain
);
}
console.log(
humantime(false) + " " + text.green + "Redundant uninstall test (error messagin" +
"g) passed." + text.nocolor
);
next();
}
);
}
);
} else {
return apps.errout({
error : "directory applications" + node.path.sep + "biddletesta changed to something el" +
"se and not deleted",
name : "biddle_test_uninstall_child_stat",
stdout: stdout,
time : humantime(true)
});
}
}
);
}
);
};
phases.unpublishAll = function biddle_test_unpublishAll() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Unpublish All tests");
node.child(
childcmd + "unpublish biddletesta all childtest",
{
cwd: data.abspath
},
function biddle_test_unpublishAll_child(er, stdout, stder) {
var unpubtest = "All versions of app " + text.cyan + "biddletesta" + text.nocolor +
" are unpublished.";
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_unpublishAll_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_unpublishAll_child", stdout: stdout, time: humantime(true)}
);
}
stdout = stdout.replace(/(\s+)$/, "");
if (stdout !== unpubtest) {
return diffFiles("biddle_test_unpublishAll_child", stdout, unpubtest);
}
console.log(
humantime(false) + " " + text.green +
"biddletesta removed from published.json." + text.nocolor
);
node
.fs
.stat(
data.abspath + "publications" + node.path.sep + "biddletesta",
function biddle_test_unpublishAll_child_stat(err, stat) {
if (err !== null && err.toString().indexOf("no such file or directory") < 0) {
return apps.errout(
{error: err, name: "biddle_test_unpublishAll_child_stat", time: humantime(true)}
);
}
if (stat !== undefined && stat.isDirectory() === true) {
return apps.errout({
error : "publications" + node.path.sep + "biddletesta directory not deleted by unpublis" +
"h command",
name : "biddle_test_unpublishAll_child_stat",
stdout: stdout,
time : humantime(true)
});
}
if (err.toString().indexOf("no such file or directory") > 0) {
node
.fs
.readFile(
data.abspath + "published.json",
function biddle_test_unpublishAll_child_stat_readfile(erf, filedata) {
var jsondata = {};
if (erf !== null && erf !== undefined) {
return apps.errout(
{error: erf, name: "biddle_test_unpublishAll_child_stat_readfile", stdout: stdout, time: humantime(true)}
);
}
jsondata = JSON.parse(filedata);
if (jsondata.biddletesta !== undefined) {
return apps.errout(
{error: "biddletesta property still present in published.json file", name: "biddle_test_unpublishAll_child_stat_readfile", stdout: stdout, time: humantime(true)}
);
}
console.log(
humantime(false) + " " + text.green + "unpublish all test passed." + text.nocolor
);
node.child(
childcmd + "unpublish biddletesta all childtest",
{
cwd: data.abspath
},
function biddle_test_unpublishAll_child_stat_readfile_again(erx, stdoutx, stderx) {
var unpubagain = "Attempted to unpublish " + text.cyan + "biddletesta" + text.nocolor + " w" +
"hich is " + text.bold + text.red + "absent" + text.none + " from the list of p" +
"ublished applications. Try using the command " + text.green + "biddle list pub" +
"lished" + text.nocolor + ".",
stack = [];
if (erx !== null) {
if (typeof erx.stack === "string") {
stack = erx
.stack
.split(" at ");
}
if (stack.length < 1 || stack[1].indexOf("ChildProcess.exithandler (child_process.js:202:12)") < 0) {
return apps.errout(
{error: erx, name: "biddle_test_unpublishAll_child_stat_readfile_again", stdout: stdout, time: humantime(true)}
);
}
}
if (stderx !== null && stderx !== "") {
return apps.errout(
{error: stderx, name: "biddle_test_unpublishAll_child_stat_readfile_again", stdout: stdout, time: humantime(true)}
);
}
stdoutx = stdoutx.replace(/(\s+)$/, "");
if (stdoutx !== unpubagain) {
return diffFiles(
"biddle_test_unpublishAll_child_stat_readfile_again",
stdoutx,
unpubagain
);
}
console.log(
humantime(false) + " " + text.green + "Redundant unpublish all test (error mess" +
"aging) passed." + text.nocolor
);
next();
}
);
}
);
} else {
return apps.errout({
error : "directory publications" + node.path.sep + "biddletesta changed to something el" +
"se and not deleted",
name : "biddle_test_unpublishAll_child_stat",
stdout: stdout,
time : humantime(true)
});
}
}
);
}
);
};
phases.unpublishB = function biddle_test_unpublishB() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Unpublish biddletestb");
node.child(
childcmd + "unpublish biddletestb all childtest",
{
cwd: data.abspath
},
function biddle_test_unpublishB_child(er, stdout, stder) {
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_unpublishB_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_unpublishB_child", stdout: stdout, time: humantime(true)}
);
}
console.log(humantime(false) + " " + text.green + "biddletestb is unpublished." + text.nocolor);
next();
}
);
};
phases.unpublishLatest = function biddle_test_unpublishLatest() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Unpublish Latest tests");
node.child(
childcmd + "unpublish biddletesta latest childtest",
{
cwd: data.abspath
},
function biddle_test_unpublishLatest_child(er, stdout, stder) {
var unpubtest = "\nVersion " + text.bold + text.red + "99.99.xxxx" + text.none +
" of app " + text.cyan + "biddletesta" + text.nocolor + " is unpublished.";
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_unpublishLatest_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_unpublishLatest_child", stdout: stdout, time: humantime(true)}
);
}
stdout = stdout.replace(/(\s+)$/, "");
stdout = stdout.replace(/\r\n/g, "\n");
stdout = stdout.replace(/99\.99\.\d\d\d\d/, "99.99.xxxx");
if (stdout !== unpubtest) {
return diffFiles("biddle_test_unpublishLatest_child", stdout, unpubtest);
}
console.log(
humantime(false) + " " + text.green +
"biddletesta removed from published.json." + text.nocolor
);
node
.fs
.stat(
data.abspath + "publications" + node.path.sep + "biddletesta",
function biddle_test_unpublishLatest_child_stat(err, stat) {
if (err !== null) {
return apps.errout(
{error: err, name: "biddle_test_unpublishLatest_child_stat", time: humantime(true)}
);
}
if (stat === undefined) {
return apps.errout({
error: "Error reading publications" + node.path.sep + "biddletesta",
name : "biddle_test_unpublishLatest_child_stat",
time : humantime(true)
});
}
node
.fs
.readFile(
data.abspath + "published.json",
function biddle_test_unpublishLatest_child_stat_readfile(erf, filedata) {
var jsondata = {};
if (erf !== null && erf !== undefined) {
return apps.errout(
{error: erf, name: "biddle_test_unpublishLatest_child_stat_readfile", stdout: stdout, time: humantime(true)}
);
}
jsondata = JSON.parse(filedata);
if (jsondata.biddletesta === undefined) {
return apps.errout(
{error: "biddletesta property prematurely deleted from published.json file", name: "biddle_test_unpublishLatest_child_stat_readfile", stdout: stdout, time: humantime(true)}
);
}
console.log(
humantime(false) + " " + text.green + "unpublish latest test passed." + text.nocolor
);
next();
}
);
}
);
}
);
};
phases.unzip = function biddle_test_unzip() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Unzip tests");
node.child(
childcmd + "unzip " + data.abspath + "unittest" + node.path.sep + "biddletesta." +
"zip " + data.abspath + "unittest" + node.path.sep + "unzip childtest",
{
cwd: data.abspath
},
function biddle_test_unzip_child(er, stdout, stder) {
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_unzip_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_unzip_child", stdout: stdout, time: humantime(true)}
);
}
node
.fs
.stat(
testpath + node.path.sep + "unzip" + node.path.sep + "biddletesta.js",
function biddle_test_unzip_child_stat(err, stat) {
if (err !== null) {
return apps.errout(
{error: err, name: "biddle_test_unzip_child_stat", stdout: stdout, time: humantime(true)}
);
}
if (stat.size < 10000) {
return apps.errout({
error : text.red + "unzip test failed." + text.nocolor,
name : "biddle_test_unzip_child_stat",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + "biddletesta.js unzipped." + text.nocolor
);
node
.fs
.readdir(
testpath + node.path.sep + "unzip",
function biddle_test_unzip_child_stat_readDir(erd, files) {
var count = 5;
if (erd !== null) {
return apps.errout(
{error: erd, name: "biddle_test_unzip_child_stat_readDir", stdout: stdout, time: humantime(true)}
);
}
if (files.length !== count) {
return apps.errout({
error : "Expected " + count + " items unzipped, but there are " + files.length + ".",
name : "biddle_test_unzip_child_stat_readDir",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + count + " items unzipped." + text.nocolor
);
console.log(
humantime(false) + " " + text.green + "unzip test passed." + text.nocolor
);
next();
}
);
return stdout;
}
);
}
);
};
phases.update = function biddle_test_update() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Update tests");
node.child(childcmd + "update biddletesta childtest", {cwd: data.abspath}, function biddle_test_update_child(er, stdout, stder) {
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_update_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_update_child", stdout: stdout, time: humantime(true)}
);
}
if (stdout.indexOf(text.yellow + "biddletesta" + text.nocolor + " updated!") < 0) {
return apps.errout({
error : "update test failed.",
name : "biddle_test_update_child",
stdout: stdout,
time : humantime(true)
});
}
console.log(humantime(false) + " " + text.green + "Update test passed." + text.nocolor);
next();
});
};
phases.zip = function biddle_test_zip() {
phasenumb = phasenumb + 1;
console.log(phasenumb + ". Zip tests");
node.child(
childcmd + "zip " + data.abspath + "test" + node.path.sep + "biddletesta " +
data.abspath + "unittest childtest",
{
cwd: data.abspath
},
function biddle_test_zip_child(er, stdout, stder) {
var ziptest = "Zip file written: unittest" + node.path.sep +
"biddletesta.zip";
if (er !== null) {
return apps.errout(
{error: er, name: "biddle_test_zip_child", stdout: stdout, time: humantime(true)}
);
}
if (stder !== null && stder !== "") {
return apps.errout(
{error: stder, name: "biddle_test_zip_child", stdout: stdout, time: humantime(true)}
);
}
stdout = stdout
.replace(/(\s+)$/, "")
.replace(data.abspath, "");
if (stdout !== ziptest) {
return diffFiles("biddle_test_zip_child", stdout, ziptest);
}
node
.fs
.stat(
testpath + node.path.sep + "biddletesta.zip",
function biddle_test_zip_stat(err, stat) {
if (err !== null) {
return apps.errout(
{error: err, name: "biddle_test_zip_stat", stdout: stdout, time: humantime(true)}
);
}
if (stat.size > 20000) {
return apps.errout({
error : "Zip file is too large at " + apps.commas(stat.size) + " bytes.",
name : "biddle_test_zip_stat",
stdout: stdout,
time : humantime(true)
});
}
console.log(
humantime(false) + " " + text.green + "zip test passed." + text.nocolor + " Fil" +
"e " + data.abspath + "unittest" + node.path.sep +
"biddletesta.zip written at " + text.bold + text.green + apps.commas(stat.size) +
text.none + " bytes."
);
next();
}
);
}
);
};
next();
};
apps.uninstall = function biddle_uninstall(fromTest) {
var app = data.installed[data.input[2]];
if (app === undefined && fromTest === false) {
return console.log(
"Attempted to uninstall " + text.cyan + data.input[2] + text.nocolor + " which " +
"is " + text.bold + text.red + "absent" + text.none + " from the list of instal" +
"led applications. Try using the command " + text.green +
"biddle list installed" + text.nocolor + "."
);
}
apps.remove(app.location, function biddle_uninstall_remove() {
if (fromTest === true) {
delete data.installed.biddletestb;
delete data.installed.biddletesta;
apps.remove(
data.abspath + "applications" + node.path.sep + "biddletestb",
function biddle_uninstall_removeTest() {
return true;
}
);
} else {
delete data.installed[data.input[2]];
}
apps.writeFile(
JSON.stringify(data.installed),
data.abspath + "installed.json",
function biddle_uninstall_remove_writeFile() {
data.input[3] = "remove";
if (data.platform !== "win32") {
apps.global(app.location + node.path.sep);
}
if (fromTest === false) {
if (data.internal === true) {
if (data.installed.internal === undefined || Object.keys(data.installed.internal).length < 1) {
apps.remove(
__dirname + node.path.sep + "internal",
function biddle_uninstall_remove_writeFile_removeInternal() {
return;
}
);
}
return console.log(
text.bold + text.red + "Internal" + text.none + " app " + text.cyan + data.input[2] +
text.nocolor + " is uninstalled."
);
}
console.log(
"App " + text.cyan + data.input[2] + text.nocolor + " is uninstalled."
);
}
}
);
});
};
apps.unpublish = function biddle_unpublish(fromTest) {
var app = {},
ver = "",
vers = [],
latest = false,
vert = false,
a = 0;
if (data.input[2] === undefined) {
if (fromTest === true) {
return apps.errout({
error: "Unpublish from biddle test failed. " + data.input[2] + " is not present in dat" +
"a.published.",
name : "biddle_unpublish"
});
}
return console.log(
"Attempted to unpublish " + text.cyan + data.input[2] + text.nocolor + " which " +
"is " + text.bold + text.red + "absent" + text.none + " from the list of publis" +
"hed applications. Try using the command " + text.green +
"biddle list published" + text.nocolor + "."
);
}
data.input[2] = apps.sanitizef(data.input[2]);
app = data.published[data.input[2]];
if (app === undefined) {
if (fromTest === true) {
return apps.errout({
error: "Unpublish from biddle test failed. " + data.input[2] + " is not present in dat" +
"a.published.",
name : "biddle_unpublish"
});
}
return console.log(
"Attempted to unpublish " + text.cyan + data.input[2] + text.nocolor + " which " +
"is " + text.bold + text.red + "absent" + text.none + " from the list of publis" +
"hed applications. Try using the command " + text.green +
"biddle list published" + text.nocolor + "."
);
}
if (data.input[3] === undefined) {
return apps.errout(
{error: "Please specify a version or \"all\" for all versions.", name: "biddle_unpublish", stdout: "", time: ""}
);
}
ver = apps.sanitizef(data.input[3]);
if (ver.toLowerCase() === "all") {
ver = "all";
} else if (ver.toLowerCase() === "latest") {
ver = app.latest;
}
vers = data
.published[data.input[2]]
.versions;
if (ver !== "all") {
a = vers.length;
do {
a = a - 1;
if (vers[a] === ver) {
vers.splice(a, 1);
vert = true;
break;
}
} while (a > 0);
if (vert === false) {
return apps.errout({
error: "Specified version, " + text.bold + text.red + ver + text.none + ", is not a pu" +
"blished version of " + text.cyan + data.input[2] + text.nocolor,
name : "biddle_unpublish"
});
}
if (app.latest === ver) {
latest = true;
}
}
if (ver === "all" || vers.length === 0) {
apps.remove(app.directory, function biddle_unpublish_remove() {
var str = "";
delete data.published[data.input[2]];
str = JSON.stringify(data.published);
apps.writeFile(
str,
data.abspath + "published.json",
function biddle_unpublish_remove_writeFile() {
if (fromTest === false) {
console.log(
"All versions of app " + text.cyan + data.input[2] + text.nocolor + " are unpub" +
"lished."
);
}
}
);
});
} else {
node
.fs
.readdir(app.directory, function biddle_unpublish_readdir(er, files) {
var later = (latest === true)
? app.versions[app.versions.length - 1]
: app.latest,
destroy = function biddle_unpublish_readdir_destroy() {
var aa = files.length,
rem = function biddle_unpublish_readdir_destroy_rem() {
apps.remove(
app.directory + files[aa],
function biddle_unpublish_readdir_destory_remove() {
return true;
}
);
};
do {
aa = aa - 1;
if (files[aa].indexOf("_" + ver + ".zip") === files[aa].length - (ver.length + 5) || files[aa].indexOf(
"_" + ver + ".hash"
) === files[aa].length - (ver.length + 6)) {
rem();
} else if (latest === true && files[aa].length > 11 && (files[aa].indexOf("_latest.zip") === files[aa].length - 11 || files[aa].indexOf("_latest.hash") === files[aa].length - 12)) {
rem();
}
} while (aa > 0);
node
.fs
.readFile(
app.directory + "filedata.json",
"utf8",
function biddle_unpublish_readdir_destory_readFileData(err, filedata) {
var parsed = {},
bb = 0;
if (err !== null && err !== undefined) {
return apps.errout(
{error: err, name: "biddle_unpublish_readdir_destory_readFileData"}
);
}
parsed = JSON
.parse(filedata)
.filedata;
bb = parsed.length;
do {
bb = bb - 1;
if (parsed[bb].filename.indexOf("_" + ver + ".zip") === parsed[bb].filename.length - (ver.length + 5) || parsed[bb].filename.indexOf(
"_" + ver + ".hash"
) === parsed[bb].filename.length - (ver.length + 6)) {
parsed.splice(bb, 1);
} else if (latest === true && (parsed[bb].filename.indexOf("_latest.zip") === parsed[bb].filename.length - 11 || parsed[bb].filename.indexOf("_latest.hash") === parsed[bb].filename.length - 12)) {
parsed.splice(bb, 1);
}
} while (bb > 0);
console.log();
apps.writeFile(
JSON.stringify({filedata: parsed}),
app.directory + "filedata.json",
function biddle_unpublish_readdir_destory_readFileData_writeFileData() {
node
.fs
.readFile(
app.directory + "index.xhtml",
"utf8",
function biddle_unpublish_readdir_destory_readFileData_writeFileData_readIndex(errr, index) {
var lex = [],
cc = 0,
dd = 0,
row = false;
if (errr !== null && errr !== undefined) {
return apps.errout(
{error: errr, name: "biddle_unpublish_readdir_destory_readFileData_writeFileData_readIndex"}
);
}
lex = index.split("");
cc = index.indexOf("") {
dd = cc + 1;
row = false;
}
if (lex[cc] === "." && lex[cc + 1] === "z" && lex[cc + 2] === "i" && lex[cc + 3] === "p" && lex[cc + 4] === "<" && lex[cc + 5] === "/" && lex[cc + 6] === "a" && lex[cc + 7] === ">") {
if (latest === true && lex.slice(cc - 7, cc).join("") === "_latest") {
row = true;
} else if (lex.slice(cc - ver.length, cc).join("") === ver) {
row = true;
}
}
if (lex[cc] === "<" && lex[cc + 1] === "t" && lex[cc + 2] === "r" && lex[cc + 3] === ">" && row === true) {
lex.splice(cc, dd - cc);
}
if (lex[cc - 5] === "<" && lex[cc - 4] === "t" && lex[cc - 3] === "b" && lex[cc - 2] === "o" && lex[cc - 1] === "d" && lex[cc] === "y") {
break;
}
} while (cc > 0);
index = lex.join("");
if (latest === true) {
dd = index.indexOf("");
cc = dd;
do {
cc = cc - 1;
} while (index.charAt(cc - 1) !== ">");
lex[0] = index.slice(cc, dd);
index = index.replace(data.input[2] + "_latest.zip", lex[0]);
}
apps.writeFile(
index,
app.directory + "index.xhtml",
function biddle_unpublish_readdir_destory_readFileData_writeFileData_readIndex_writeIndex() {
apps.writeFile(
JSON.stringify(data.published),
data.abspath + "published.json",
function biddle_unpublish_readdir_destory_readFileData_writeFileData_readIndex_writeIndex_writePublished() {
if (fromTest === false) {
console.log(
"Version " + text.bold + text.red + ver + text.none + " of app " + text.cyan +
data.input[2] + text.nocolor + " is unpublished."
);
}
}
);
}
);
}
);
}
);
}
);
};
if (er !== null) {
return apps.errout({error: er, name: "biddle_unpublish_readdir"});
}
if (latest === true) {
data
.published[data.input[2]]
.latest = later;
apps.writeFile(later, app.directory + "latest.txt", destroy);
} else {
destroy();
}
});
}
};
apps.update = function biddle_update(app, forceInternal, callback) {
var inst = {};
if (forceInternal === true) {
inst = data.installed.internal[app];
} else {
inst = data.installed[app];
}
if (inst === undefined && app !== undefined) {
return apps.errout({
error: "Update failed, " + text.cyan + app + text.nocolor + " is not installed by bidd" +
"le.",
name : "biddle_update"
});
}
apps.status(app, forceInternal, function biddle_update_statusResponse(status) {
var zippy = "";
if (status === undefined) {
return;
}
if (status.indexOf("matches published version") > 0) {
console.log(status);
return callback();
}
console.log(status);
zippy = inst.published;
if (data.protocoltest.test(inst.published) === true && inst.published.charAt(inst.published.length - 1) !== "/") {
zippy = zippy + "/"
} else if (data.protocoltest.test(inst.published) === false && inst.published.charAt(inst.published.length - 1) !== node.path.sep) {
zippy = zippy + node.path.sep;
}
zippy = zippy + app + "_";
if (inst.variant !== "") {
zippy = zippy + inst.variant + "_";
}
zippy = zippy + "latest.zip";
apps.install(zippy, callback);
});
};
apps.writeFile = function biddle_writeFile(fileData, fileName, callback) {
var callbacker = function biddle_writeFile_callbacker(size) {
var colored = [];
if (size > 0 && fileName.replace(data.abspath, "") !== "published.json" && fileName.replace(data.abspath, "") !== "installed.json") {
colored = fileName.split(node.path.sep);
colored[colored.length - 1] = colored[colored.length - 1].replace(
"_",
"_" + text.bold + text.cyan
);
if ((/((\.zip)|(\.hash))$/).test(fileName) === true) {
console.log(
"File " + colored.join(node.path.sep) + text.none + " written at " + text.bold +
text.green + apps.commas(size) + text.none + " bytes."
);
} else {
console.log(
"File " + colored.join(node.path.sep) + " written at " + text.bold + text.green +
apps.commas(size) + text.none + " bytes."
);
}
}
callback(fileData);
},
encoding = (
typeof fileData !== "string" && ((data.command !== "install" && (/[\u0002-\u0008]|[\u000e-\u001f]/).test(fileData) === true) || (/(\.zip)$/).test(fileName) === true)
)
? "binary"
: "utf8";
node
.fs
.writeFile(
fileName,
fileData,
encoding,
function biddle_writeFile_callback(err) {
if (err !== null) {
if (data.platform !== "win32" && data.command === "global" && err.toString().indexOf("EACCES: permission denied")) {
return apps.errout({
error: err.toString() + "\n" + text.bold + text.red + "This command requires sudo acce" +
"ss." + text.none + " Please try 'sudo node biddle global'.",
name : "biddle_writeFile_callback"
});
}
return apps.errout({error: err, name: "biddle_writeFile_callback"});
}
if (data.command === "get" || data.command === "publish") {
if (data.command === "publish") {
fileName = fileName.replace(".hash", ".zip");
}
node
.fs
.stat(fileName, function biddle_writeFile_callback_getstat(errstat, stat) {
if (errstat !== null) {
return apps.errout({error: errstat, name: "biddle_writeFile_callback_getstat"});
}
callbacker(stat.size);
});
} else {
callbacker(0);
}
}
);
};
apps.version = function biddle_version() {
if (data.input[2] === undefined) {
apps.getpjson(data.abspath + "package.json", function biddle_version_vers() {
console.log(
text.cyan + "biddle" + text.nocolor + " - " + data.packjson.version
);
});
} else {
if (data.installed[data.input[2]] === undefined) {
apps.errout({
error: text.red + data.input[2] + text.nocolor + " is not installed by biddle",
name : "biddle_version"
});
} else {
console.log(
text.cyan + data.input[2] + text.nocolor + " - " + data.installed[data.input[2]].version
);
}
}
};
apps.zip = function biddle_zip(callback, zippack) {
var zipfile = "",
latestfile = "",
cmd = "",
latestcmd = "",
zipdir = "",
variantName = (zippack.name === "")
? ""
: "_" + apps.sanitizef(zippack.name),
childfunc = function biddle_zip_childfunc(zipfilename, zipcmd) {
node.child(zipcmd, {
cwd: zipdir
}, function biddle_zip_childfunc_child(err, stdout, stderr) {
if (err !== null && stderr.toString().indexOf("No such file or directory") < 0) {
return apps.errout({error: err, name: "biddle_zip_childfunc_child"});
}
if (stderr !== null && stderr.replace(/\s+/, "") !== "" && stderr.indexOf("No such file or directory") < 0) {
return apps.errout({error: stderr, name: "biddle_zip_childfunc_child"});
}
if (data.command === "test" && data.internal === true) {
data.address.target = zipdir + node.path.sep;
}
callback(zipfilename);
return stdout;
});
};
if (data.command === "publish" || data.command === "zip") {
if (data.command === "zip") {
zipfile = data.address.target + zippack.fileName + ".zip";
} else {
zipfile = data.address.target + data.packjson.name + variantName + "_" + apps.sanitizef(
data.packjson.version
) + ".zip";
}
if (data.command === "publish") {
cmd = cmds.zip(zipfile, "");
apps.makedir(data.address.target, function biddle_zip_makepubdir() {
zipdir = zippack.location;
if (data.latestVersion === true) {
latestfile = zipfile.replace(data.packjson.version + ".zip", "latest.zip");
latestcmd = cmd.replace(data.packjson.version + ".zip", "latest.zip");
apps.remove(latestfile, function biddle_zip_makepubdir_removeFile() {
childfunc(latestfile, latestcmd);
});
}
childfunc(zipfile, cmd);
});
} else {
node
.fs
.stat(data.input[2], function biddle_zip_stat(ers, stats) {
if (ers !== null) {
return apps.errout({error: ers, name: "biddle_zip_stat"});
}
if (stats.isDirectory() === true) {
cmd = cmds.zip(zipfile, "");
apps.makedir(data.input[2], function biddle_zip_stat_makedir() {
zipdir = data.input[2];
childfunc(zipfile, cmd);
});
} else {
zipdir = (function biddle_zip_stat_zipdir() {
var dirs = data
.input[2]
.split(node.path.sep);
cmd = cmds.zip(zipfile, dirs.pop());
return apps.relToAbs(dirs.join(node.path.sep), data.cwd);
}());
childfunc(zipfile, cmd);
}
});
}
}
if (data.command === "install" || data.command === "test" || data.command === "unzip" || data.command === "update") {
if (data.command === "test" && data.internal === true) {
zipdir = zippack.fileName;
zipdir = zipdir.replace(/((_latest)?\.zip)$/i, "");
if (zipdir.indexOf("_") > 0) {
zipdir = zipdir.slice(0, zipdir.indexOf("_"));
}
zipdir = __dirname + node.path.sep + "internal" + node.path.sep + zipdir;
cmd = cmds.unzip(data.address.downloads + zippack.fileName, zipdir);
apps.makedir(zipdir, function biddle_zip_unzip() {
childfunc(data.address.downloads + zippack.fileName, cmd);
});
} else {
apps.remove(data.address.target, function biddle_zip_remove() {
if (data.command === "unzip") {
cmd = cmds.unzip(data.input[2], data.address.target);
} else {
cmd = cmds.unzip(
data.address.downloads + zippack.fileName,
data.address.target
);
}
apps.makedir(data.address.target, function biddle_zip_remove_unzip() {
childfunc(data.input[2], cmd);
});
});
}
}
};
(function biddle_init() {
var status = {
biddlerc : false,
installed: false,
published: false
},
valuetype = "",
start = function biddle_init_start() {
(function biddle_init_start_target() {
var dir = [],
app = "";
if (typeof data.input[3] === "string" && (data.command !== "install" || data.internal === false)) {
data.address.target = apps.relToAbs(
data.input[3].replace(/((\\|\/)+)$/, ""),
data.cwd
) + node.path.sep;
} else if (data.command === "publish") {
data.address.target = data.address.publications;
} else if (data.command === "install" || data.command === "update") {
dir = (data.protocoltest.test(data.input[2]) === true)
? data
.input[2]
.split("/")
: data
.input[2]
.split(node.path.sep);
app = dir[dir.length - 1];
if (data.internal === true) {
data.address.target = __dirname + node.path.sep + "internal" + node.path.sep +
apps.sanitizef(app.slice(0, app.indexOf("_"))) + node.path.sep;
} else if (app.indexOf("_") > -1) {
data.address.target = data.address.applications + apps.sanitizef(
app.slice(0, app.indexOf("_"))
) + node.path.sep;
} else {
data.address.target = data.address.applications + apps.sanitizef(app) + node.path.sep;
}
} else {
data.address.target = data.address.downloads;
}
}());
if (data.command === "help" || data.command === "" || data.command === undefined || data.command === "?") {
if (data.command === "") {
data.command = "help";
data.input[1] = "help";
data.input[2] = "80";
}
apps.markdown();
} else if (isNaN(data.command) === false) {
data.input[1] = "markdown";
data.input[2] = data.command;
data.command = "markdown";
apps.markdown();
} else if (commands[data.command] === undefined && commands[data.command + "s"] === undefined) {
apps.commands();
console.log("");
apps.errout({
error: "Unrecognized command: " + text.red + text.bold + data.command + text.none,
name : "biddle_init_start"
});
} else {
if (data.input[2] === undefined && data.command !== "command" && data.command !== "global" && data.command !== "list" && data.command !== "status" && data.command !== "update" && data.command !== "test" && data.command !== "version") {
if (data.command === "copy" || data.command === "hash" || data.command === "markdown" || data.command === "remove" || data.command === "unzip" || data.command === "zip") {
valuetype = "path to a local file or directory";
} else if (data.command === "get" || data.command === "install" || data.command === "publish") {
valuetype = "URL address for a remote resource or path to a local file";
} else if (data.command === "uninstall" || data.command === "unpublish") {
valuetype = "known application name";
}
return apps.errout({
error: "Command " + text.green + data.command + text.nocolor + " requires a " +
valuetype + ".",
name : "biddle_init_start"
});
}
if (data.input[3] === undefined && data.command === "copy") {
return apps.errout({
error: "Command " + text.green + data.command + text.nocolor + " requires a destinatio" +
"n directory.",
name : "biddle_init_start"
});
}
if (data.command === "command" || data.command === "commands") {
apps.commands();
} else if (data.command === "copy") {
apps.copy(data.input[2], data.input[3], [], function biddle_init_start_copy() {
return true;
});
} else if (data.command === "get") {
apps.get(
data.input[2],
apps.getFileName(data.input[2]),
function biddle_init_start_getback(filedata) {
apps.writeFile(
filedata,
data.address.target + data.fileName,
function biddle_init_start_getback_callback() {
return filedata;
}
);
}
);
} else if (data.command === "global") {
apps.global(data.abspath);
} else if (data.command === "hash") {
apps.hash(data.input[2], "hashFile", function biddle_init_start_hash() {
console.log(data.hashFile);
});
} else if (data.command === "install") {
apps.install(data.input[2], function biddle_init_start_installCallback() {
if (data.internal === true) {
return console.log(
"Application " + text.cyan + data.packjson.name + text.nocolor +
" is installed " + text.bold + text.yellow + "internally to biddle" + text.none +
" at version: " + text.bold + text.green + data.packjson.version + text.none
);
}
console.log(
"Application " + text.cyan + data.packjson.name + text.nocolor + " is installed" +
" to version: " + text.bold + text.green + data.packjson.version + text.none
);
});
} else if (data.command === "list") {
apps.list();
} else if (data.command === "markdown") {
apps.markdown();
} else if (data.command === "publish") {
apps.publish();
} else if (data.command === "remove") {
apps.remove(data.input[2], function biddle_init_start_remove() {
return true;
});
} else if (data.command === "status") {
apps.status(data.input[2], false, function biddle_init_start_status(status) {
console.log(status);
});
} else if (data.command === "test") {
apps.test();
} else if (data.command === "uninstall") {
apps.uninstall(false);
} else if (data.command === "unpublish") {
apps.unpublish(false);
} else if (data.command === "unzip") {
apps.zip(function biddle_init_start_unzip(zipfilename) {
console.log("File " + zipfilename + " unzipped to: " + data.address.target);
return [zipfilename];
}, {
location: apps.relToAbs(data.input[2], data.cwd),
name : ""
});
} else if (data.command === "update") {
apps.update(data.input[2], false, function biddle_init_start_update() {
console.log(text.yellow + data.input[2] + text.nocolor + " updated!");
});
} else if (data.command === "version") {
apps.version();
} else if (data.command === "zip") {
apps.zip(function biddle_init_start_zip(zipfilename) {
console.log("Zip file written: " + zipfilename);
return [zipfilename];
}, {
fileName: (function biddle_install_late() {
var sep = (data.protocoltest.test(data.input[2]) === true)
? "/"
: node.path.sep,
dirs = data
.input[2]
.split(sep);
return dirs.pop();
}()),
location: apps.relToAbs(data.input[2], data.cwd),
name : ""
});
}
}
};
data.input = (function biddle_input() {
var a = [],
b = 0,
c = process.argv.length,
int = -1,
paths = [];
if (process.argv[0] === "sudo") {
process
.argv
.splice(0, 1);
data.sudo = true;
}
paths = process
.argv[0]
.split(node.path.sep);
if (paths[paths.length - 1] === "node" || paths[paths.length - 1] === "node.exe") {
b = 1;
}
do {
a.push(process.argv[b]);
b = b + 1;
} while (b < c);
if (a.length < 1) {
a = ["", "", ""];
}
a[0] = a[0].toLowerCase();
if (a[a.length - 1] === "childtest") {
a.pop();
data.childtest = true;
}
int = a.indexOf("--internal");
if (int > -1) {
data.internal = true;
a.splice(int, 1);
}
return a;
}());
data.command = (data.input.length > 1)
? (data.command[
data
.input[1]
.toLowerCase()
.replace(/(s\s*)$/, "")
] === undefined && data.input[1].toLowerCase() !== "status")
? data
.input[1]
.toLowerCase()
.replace(/(s\s*)$/, "")
.replace(/^(-+)/, "")
: data
.input[1]
.toLowerCase()
: "";
if (data.command === "v" || data.command === "ver") {
data.command = "version";
}
if (data.command === "h") {
data.command = "help";
}
data.abspath = (function biddle_abspath() {
var absarr = data
.input[0]
.split(node.path.sep);
absarr.pop();
if (absarr[absarr.length - 1] === "bin") {
absarr.pop();
}
if (absarr[absarr.length - 1] !== "biddle") {
absarr.push("biddle");
}
return absarr.join(node.path.sep) + node.path.sep;
}());
data.platform = process
.platform
.replace(/\s+/g, "")
.toLowerCase();
data.address.applications = data.abspath + "applications" + node.path.sep;
data.address.downloads = data.abspath + "downloads" + node.path.sep;
data.address.publications = data.abspath + "publications" + node.path.sep;
node
.fs
.readFile(
data.abspath + "installed.json",
"utf8",
function biddle_init_installed(err, fileData) {
var parsed = {};
if (err !== null && err !== undefined) {
return apps.errout({error: err, name: "biddle_init_installed"});
}
if (fileData !== "") {
parsed = JSON.parse(fileData);
}
data.installed = parsed;
if (data.internal === true && (data.command === "list" || data.command === "install" || data.command === "status" || data.command === "update")) {
if (data.installed.internal === undefined) {
data.installed = {};
} else {
data.installed = data.installed.internal;
}
} else if (data.command !== "install" && data.command !== "update" && data.command !== "uninstall" && (data.command !== "test" || (data.command === "test" && data.input[2] !== undefined && data.input[2] !== "biddle"))) {
delete data.installed.internal;
}
status.installed = true;
if (status.published === true && status.biddlerc === true) {
start();
}
}
);
node
.fs
.readFile(
data.abspath + "published.json",
"utf8",
function biddle_init_published(err, fileData) {
var parsed = {};
if (err !== null && err !== undefined) {
return apps.errout({error: err, name: "biddle_init_published"});
}
if (fileData !== "") {
parsed = JSON.parse(fileData);
}
data.published = parsed;
status.published = true;
if (status.installed === true && status.biddlerc === true) {
start();
}
}
);
if (data.command === "get" || data.command === "install" || data.command === "publish") {
if (data.input.length < 3) {
return apps.errout({
error: "Biddle command " + text.yellow + text.bold + data.command + text.none + " requ" +
"ires an address or file path.",
name : "biddle_init"
});
}
(function biddle_init_biddlerc() {
var pubdir = apps.relToAbs(data.input[2].replace(/((\/|\\)+)$/, ""), data.cwd) +
node.path.sep,
rcpath = (data.command === "publish")
? pubdir + ".biddlerc"
: process.cwd() + node.path.sep + ".biddlerc";
node
.fs
.readFile(
rcpath,
"utf8",
function biddle_init_biddlerc_readFile(err, fileData) {
var parsed = {},
dirs = function biddle_init_biddlerc_dirs(type) {
if (typeof parsed.directories[type] === "string") {
if (parsed.directories[type].length > 0) {
if (data.command === "publish") {
data.address[type] = apps.relToAbs(parsed.directories[type], pubdir) + node.path.sep;
} else {
data.address[type] = apps.relToAbs(parsed.directories[type], data.abspath) +
node.path.sep;
}
data
.ignore
.push(parsed.directories[type]);
return;
}
}
};
if (err !== null && err !== undefined) {
if (err.toString().indexOf("no such file or directory") > 0) {
status.biddlerc = true;
if (status.installed === true && status.published === true) {
start();
}
return;
}
return apps.errout({error: err, name: "biddle_init_biddlerc_readFile"});
}
parsed = JSON.parse(fileData);
dirs("applications");
dirs("downloads");
dirs("publications");
if (typeof parsed.exclusions === "object" && parsed.exclusions.length > 0) {
parsed
.exclusions
.forEach(function biddle_init_biddlerc_readFile_exclusions(value) {
data
.ignore
.push(value.replace(/\\|\//g, node.path.sep));
});
data
.ignore
.push(".biddlerc");
}
status.biddlerc = true;
if (status.installed === true && status.published === true) {
start();
}
}
);
}());
} else {
status.biddlerc = true;
if (status.installed === true && status.published === true) {
start();
}
}
}());
}());