mirror of https://gitee.com/bigwinds/arangodb
Created a foxx store module that wraps around the foxx application store. It is now used from the client and server side foxx manager
This commit is contained in:
parent
ac1d0e37c1
commit
bf9f3fc3a8
|
@ -45,6 +45,7 @@ var checkParameter = arangodb.checkParameter;
|
||||||
var arango = require("internal").arango;
|
var arango = require("internal").arango;
|
||||||
var download = require("internal").download;
|
var download = require("internal").download;
|
||||||
var utils = require("org/arangodb/foxx/manager-utils");
|
var utils = require("org/arangodb/foxx/manager-utils");
|
||||||
|
var store = require("org/arangodb/foxx/store");
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- private functions
|
// --SECTION-- private functions
|
||||||
|
@ -60,37 +61,6 @@ function getStorage () {
|
||||||
return db._collection('_aal');
|
return db._collection('_aal');
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief returns the fishbowl collection
|
|
||||||
/// this will create the collection if it does not exist. this is better than
|
|
||||||
/// needlessly creating the collection for each database in case it is not
|
|
||||||
/// used in context of the database.
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
function getFishbowlStorage () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
return utils.getFishbowlStorage();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief validate an app name and fail if it is invalid
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
function validateAppName (name) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
if (typeof name === 'string' && name.length > 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new ArangoError({
|
|
||||||
errorNum: errors.ERROR_APPLICATION_INVALID_NAME.code,
|
|
||||||
errorMessage: errors.ERROR_APPLICATION_INVALID_NAME.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief validate a mount and fail if it is invalid
|
/// @brief validate a mount and fail if it is invalid
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -172,27 +142,6 @@ function processSource (src) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief comparator for applications
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
function compareApps (l, r) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var left = l.name.toLowerCase();
|
|
||||||
var right = r.name.toLowerCase();
|
|
||||||
|
|
||||||
if (left < right) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (right < left) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief prints out usage message for the command-line tool
|
/// @brief prints out usage message for the command-line tool
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -223,7 +172,7 @@ function fetchGithubForInstall (name) {
|
||||||
// latest fishbowl version
|
// latest fishbowl version
|
||||||
// .............................................................................
|
// .............................................................................
|
||||||
|
|
||||||
var fishbowl = getFishbowlStorage();
|
var fishbowl = store.getFishbowlStorage();
|
||||||
var available = fishbowl.firstExample({name: name});
|
var available = fishbowl.firstExample({name: name});
|
||||||
var source = null;
|
var source = null;
|
||||||
var version = null;
|
var version = null;
|
||||||
|
@ -250,9 +199,10 @@ function fetchGithubForInstall (name) {
|
||||||
var appId = null;
|
var appId = null;
|
||||||
var aal = getStorage();
|
var aal = getStorage();
|
||||||
var cursor = aal.byExample({ type: "app", name: name });
|
var cursor = aal.byExample({ type: "app", name: name });
|
||||||
|
var doc;
|
||||||
|
|
||||||
while (cursor.hasNext()) {
|
while (cursor.hasNext()) {
|
||||||
var doc = cursor.next();
|
doc = cursor.next();
|
||||||
|
|
||||||
if (module.compareVersions(version, doc.version) <= 0) {
|
if (module.compareVersions(version, doc.version) <= 0) {
|
||||||
version = doc.version;
|
version = doc.version;
|
||||||
|
@ -299,14 +249,15 @@ function extractCommandLineOptions (args) {
|
||||||
|
|
||||||
var re1 = /^([\-_a-zA-Z0-9]*)=(.*)$/;
|
var re1 = /^([\-_a-zA-Z0-9]*)=(.*)$/;
|
||||||
var re2 = /^(0|.0|([0-9]*(\.[0-9]*)?))$/;
|
var re2 = /^(0|.0|([0-9]*(\.[0-9]*)?))$/;
|
||||||
|
var a, m, k, v;
|
||||||
|
|
||||||
for (i = 0; i < args.length; ++i) {
|
for (i = 0; i < args.length; ++i) {
|
||||||
var a = args[i];
|
a = args[i];
|
||||||
var m = re1.exec(a);
|
m = re1.exec(a);
|
||||||
|
|
||||||
if (m !== null) {
|
if (m !== null) {
|
||||||
var k = m[1];
|
k = m[1];
|
||||||
var v = m[2];
|
v = m[2];
|
||||||
|
|
||||||
if (re2.test(v)) {
|
if (re2.test(v)) {
|
||||||
options[k] = parseFloat(v);
|
options[k] = parseFloat(v);
|
||||||
|
@ -334,7 +285,7 @@ function extractCommandLineOptions (args) {
|
||||||
exports.run = function (args) {
|
exports.run = function (args) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
if (typeof args === 'undefined' || args.length === 0) {
|
if (args === undefined || args.length === 0) {
|
||||||
arangodb.print("Expecting a command, please try:\n");
|
arangodb.print("Expecting a command, please try:\n");
|
||||||
cmdUsage();
|
cmdUsage();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -441,16 +392,16 @@ exports.run = function (args) {
|
||||||
exports.fetched();
|
exports.fetched();
|
||||||
}
|
}
|
||||||
else if (type === 'available') {
|
else if (type === 'available') {
|
||||||
exports.available();
|
store.available();
|
||||||
}
|
}
|
||||||
else if (type === 'info') {
|
else if (type === 'info') {
|
||||||
exports.info(args[1]);
|
store.info(args[1]);
|
||||||
}
|
}
|
||||||
else if (type === 'search') {
|
else if (type === 'search') {
|
||||||
exports.search(args[1]);
|
store.search(args[1]);
|
||||||
}
|
}
|
||||||
else if (type === 'update') {
|
else if (type === 'update') {
|
||||||
exports.update();
|
store.update();
|
||||||
}
|
}
|
||||||
else if (type === 'help') {
|
else if (type === 'help') {
|
||||||
exports.help();
|
exports.help();
|
||||||
|
@ -495,11 +446,11 @@ exports.fetch = function (type, location, version) {
|
||||||
|
|
||||||
var filename = processSource(source);
|
var filename = processSource(source);
|
||||||
|
|
||||||
if (typeof source.name === "undefined") {
|
if (source.name === undefined) {
|
||||||
throwBadParameter("Name missing for '" + JSON.stringify(source) + "'");
|
throwBadParameter("Name missing for '" + JSON.stringify(source) + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof source.version === "undefined") {
|
if (source.version === undefined) {
|
||||||
throwBadParameter("Version missing for '" + JSON.stringify(source) + "'");
|
throwBadParameter("Version missing for '" + JSON.stringify(source) + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,7 +496,7 @@ exports.mount = function (appId, mount, options) {
|
||||||
options: options
|
options: options
|
||||||
};
|
};
|
||||||
|
|
||||||
validateAppName(appId);
|
utils.validateAppName(appId);
|
||||||
validateMount(mount);
|
validateMount(mount);
|
||||||
|
|
||||||
var res = arango.POST("/_admin/foxx/mount", JSON.stringify(req));
|
var res = arango.POST("/_admin/foxx/mount", JSON.stringify(req));
|
||||||
|
@ -609,7 +560,7 @@ exports.unmount = function (mount) {
|
||||||
[ [ "Mount identifier", "string" ] ],
|
[ [ "Mount identifier", "string" ] ],
|
||||||
[ mount ] );
|
[ mount ] );
|
||||||
|
|
||||||
validateAppName(mount);
|
utils.validateAppName(mount);
|
||||||
|
|
||||||
var req = {
|
var req = {
|
||||||
mount: mount
|
mount: mount
|
||||||
|
@ -654,7 +605,7 @@ exports.replace = function (name, mount, options) {
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (typeof options.setup === "undefined") {
|
if (options.setup === undefined) {
|
||||||
options.setup = true;
|
options.setup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,7 +651,7 @@ exports.install = function (name, mount, options) {
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (typeof options.setup === "undefined") {
|
if (options.setup === undefined) {
|
||||||
options.setup = true;
|
options.setup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -839,15 +790,13 @@ exports.fetchedJson = function () {
|
||||||
var aal = getStorage();
|
var aal = getStorage();
|
||||||
var cursor = aal.byExample({ type: "app" });
|
var cursor = aal.byExample({ type: "app" });
|
||||||
var result = [];
|
var result = [];
|
||||||
|
var doc, res;
|
||||||
|
|
||||||
while (cursor.hasNext()) {
|
while (cursor.hasNext()) {
|
||||||
var doc = cursor.next();
|
doc = cursor.next();
|
||||||
|
|
||||||
if (doc.isSystem) {
|
if (!doc.isSystem) {
|
||||||
continue;
|
res = {
|
||||||
}
|
|
||||||
|
|
||||||
var res = {
|
|
||||||
appId: doc.app,
|
appId: doc.app,
|
||||||
name: doc.name,
|
name: doc.name,
|
||||||
description: doc.description || "",
|
description: doc.description || "",
|
||||||
|
@ -855,9 +804,9 @@ exports.fetchedJson = function () {
|
||||||
version: doc.version,
|
version: doc.version,
|
||||||
path: doc.path
|
path: doc.path
|
||||||
};
|
};
|
||||||
|
|
||||||
result.push(res);
|
result.push(res);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
@ -889,191 +838,6 @@ exports.fetched = function () {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief returns all available FOXX applications
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
exports.availableJson = function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
return utils.availableJson();
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief prints all available FOXX applications
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
exports.available = function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var list = exports.availableJson();
|
|
||||||
|
|
||||||
arangodb.printTable(
|
|
||||||
list.sort(compareApps),
|
|
||||||
[ "name", "author", "description", "latestVersion" ],
|
|
||||||
{
|
|
||||||
prettyStrings: true,
|
|
||||||
totalString: "%s application(s) found",
|
|
||||||
emptyString: "no applications found, please use 'update'",
|
|
||||||
rename: {
|
|
||||||
"name" : "Name",
|
|
||||||
"author" : "Author",
|
|
||||||
"description" : "Description",
|
|
||||||
"latestVersion" : "Latest Version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief info for an available FOXX application
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
exports.info = function (name) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
validateAppName(name);
|
|
||||||
|
|
||||||
var fishbowl = getFishbowlStorage();
|
|
||||||
|
|
||||||
if (fishbowl.count() === 0) {
|
|
||||||
arangodb.print("Repository is empty, please use 'update'");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var desc;
|
|
||||||
|
|
||||||
try {
|
|
||||||
desc = fishbowl.document(name);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
arangodb.print("No application '" + name + "' available, please try 'search'");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
arangodb.printf("Name: %s\n", desc.name);
|
|
||||||
|
|
||||||
if (desc.hasOwnProperty('author')) {
|
|
||||||
arangodb.printf("Author: %s\n", desc.author);
|
|
||||||
}
|
|
||||||
|
|
||||||
var isSystem = desc.hasOwnProperty('isSystem') && desc.isSystem;
|
|
||||||
arangodb.printf("System: %s\n", JSON.stringify(isSystem));
|
|
||||||
|
|
||||||
if (desc.hasOwnProperty('description')) {
|
|
||||||
arangodb.printf("Description: %s\n\n", desc.description);
|
|
||||||
}
|
|
||||||
|
|
||||||
var header = false;
|
|
||||||
var versions = Object.keys(desc.versions);
|
|
||||||
versions.sort(module.compareVersions);
|
|
||||||
|
|
||||||
versions.forEach(function (v) {
|
|
||||||
var version = desc.versions[v];
|
|
||||||
|
|
||||||
if (! header) {
|
|
||||||
arangodb.print("Versions:");
|
|
||||||
header = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version.type === "github") {
|
|
||||||
if (version.hasOwnProperty("tag")) {
|
|
||||||
arangodb.printf('%s: fetch github "%s" "%s"\n', v, version.location, version.tag);
|
|
||||||
}
|
|
||||||
else if (v.hasOwnProperty("branch")) {
|
|
||||||
arangodb.printf('%s: fetch github "%s" "%s"\n', v, version.location, version.branch);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
arangodb.printf('%s: fetch "github" "%s"\n', v, version.location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
arangodb.printf("\n");
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief returns the search result for FOXX applications
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
exports.searchJson = function (name) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var fishbowl = getFishbowlStorage();
|
|
||||||
|
|
||||||
if (fishbowl.count() === 0) {
|
|
||||||
arangodb.print("Repository is empty, please use 'update'");
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
var docs;
|
|
||||||
|
|
||||||
if (name === undefined || (typeof name === "string" && name.length === 0)) {
|
|
||||||
docs = fishbowl.toArray();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
name = name.replace(/[^a-zA-Z0-9]/g, ' ');
|
|
||||||
|
|
||||||
// get results by looking in "description" attribute
|
|
||||||
docs = fishbowl.fulltext("description", "prefix:" + name).toArray();
|
|
||||||
|
|
||||||
// build a hash of keys
|
|
||||||
var i;
|
|
||||||
var keys = { };
|
|
||||||
|
|
||||||
for (i = 0; i < docs.length; ++i) {
|
|
||||||
keys[docs[i]._key] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get results by looking in "name" attribute
|
|
||||||
var docs2= fishbowl.fulltext("name", "prefix:" + name).toArray();
|
|
||||||
|
|
||||||
// merge the two result sets, avoiding duplicates
|
|
||||||
for (i = 0; i < docs2.length; ++i) {
|
|
||||||
if (keys.hasOwnProperty(docs2[i]._key)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
docs.push(docs2[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return docs;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief searchs for an available FOXX applications
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
exports.search = function (name) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var docs = exports.searchJson(name);
|
|
||||||
|
|
||||||
arangodb.printTable(
|
|
||||||
docs.sort(compareApps),
|
|
||||||
[ "name", "author", "description" ],
|
|
||||||
{
|
|
||||||
prettyStrings: true,
|
|
||||||
totalString: "%s application(s) found",
|
|
||||||
emptyString: "no applications found",
|
|
||||||
rename: {
|
|
||||||
name : "Name",
|
|
||||||
author : "Author",
|
|
||||||
description : "Description"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief updates the repository
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
exports.update = utils.updateFishbowl;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief outputs the help
|
/// @brief outputs the help
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1112,10 +876,11 @@ exports.help = function () {
|
||||||
var keys = Object.keys(commands).sort();
|
var keys = Object.keys(commands).sort();
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
|
var pad, name, extra;
|
||||||
for (i = 0; i < keys.length; ++i) {
|
for (i = 0; i < keys.length; ++i) {
|
||||||
var pad = " ";
|
pad = " ";
|
||||||
var name = keys[i] + pad;
|
name = keys[i] + pad;
|
||||||
var extra = commands[keys[i]];
|
extra = commands[keys[i]];
|
||||||
|
|
||||||
if (typeof extra !== 'string') {
|
if (typeof extra !== 'string') {
|
||||||
// list of strings
|
// list of strings
|
||||||
|
@ -1165,6 +930,17 @@ exports.devTeardown = function (name) {
|
||||||
arangosh.checkRequestResult(res);
|
arangosh.checkRequestResult(res);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Exports from foxx store module.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
exports.available = store.available;
|
||||||
|
exports.availableJson = store.availableJson;
|
||||||
|
exports.search = store.search;
|
||||||
|
exports.searchJson = store.searchJson;
|
||||||
|
exports.update = store.update;
|
||||||
|
exports.info = store.info;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*global require, exports, module */
|
/*global require, exports */
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief ArangoDB Application Launcher Utilities
|
/// @brief ArangoDB Application Launcher Utilities
|
||||||
|
@ -33,10 +33,11 @@ var fs = require("fs");
|
||||||
var arangodb = require("org/arangodb");
|
var arangodb = require("org/arangodb");
|
||||||
var db = arangodb.db;
|
var db = arangodb.db;
|
||||||
var download = require("internal").download;
|
var download = require("internal").download;
|
||||||
var checkedFishBowl = false;
|
|
||||||
|
|
||||||
var throwFileNotFound = arangodb.throwFileNotFound;
|
var throwFileNotFound = arangodb.throwFileNotFound;
|
||||||
var throwDownloadError = arangodb.throwDownloadError;
|
var throwDownloadError = arangodb.throwDownloadError;
|
||||||
|
var errors = arangodb.errors;
|
||||||
|
var ArangoError = arangodb.ArangoError;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief builds a github repository URL
|
/// @brief builds a github repository URL
|
||||||
|
@ -235,67 +236,6 @@ function processGithubRepository (source) {
|
||||||
repackZipFile(source);
|
repackZipFile(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief returns the fishbowl collection
|
|
||||||
///
|
|
||||||
/// this will create the collection if it does not exist. this is better than
|
|
||||||
/// needlessly creating the collection for each database in case it is not
|
|
||||||
/// used in context of the database.
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
function getFishbowlStorage () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var c = db._collection('_fishbowl');
|
|
||||||
if (c === null) {
|
|
||||||
c = db._create('_fishbowl', { isSystem : true });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c !== null && ! checkedFishBowl) {
|
|
||||||
// ensure indexes
|
|
||||||
c.ensureFulltextIndex("description");
|
|
||||||
c.ensureFulltextIndex("name");
|
|
||||||
checkedFishBowl = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief returns all available FOXX applications
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
function availableJson() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var fishbowl = getFishbowlStorage();
|
|
||||||
var cursor = fishbowl.all();
|
|
||||||
var result = [];
|
|
||||||
|
|
||||||
while (cursor.hasNext()) {
|
|
||||||
var doc = cursor.next();
|
|
||||||
|
|
||||||
var maxVersion = "-";
|
|
||||||
var versions = Object.keys(doc.versions);
|
|
||||||
versions.sort(module.compareVersions);
|
|
||||||
if (versions.length > 0) {
|
|
||||||
versions.reverse();
|
|
||||||
maxVersion = versions[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
var res = {
|
|
||||||
name: doc.name,
|
|
||||||
description: doc.description || "",
|
|
||||||
author: doc.author || "",
|
|
||||||
latestVersion: maxVersion
|
|
||||||
};
|
|
||||||
|
|
||||||
result.push(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns the aal collection
|
/// @brief returns the aal collection
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -346,170 +286,34 @@ function listJson (showPrefix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief returns the fishbowl repository
|
/// @brief validate an app name and fail if it is invalid
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
function getFishbowlUrl () {
|
function validateAppName (name) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return "arangodb/foxx-apps";
|
if (typeof name === 'string' && name.length > 0) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
throw new ArangoError({
|
||||||
/// @brief updates the fishbowl from a zip archive
|
errorNum: errors.ERROR_APPLICATION_INVALID_NAME.code,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
errorMessage: errors.ERROR_APPLICATION_INVALID_NAME.message
|
||||||
|
|
||||||
function updateFishbowlFromZip (filename) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var i;
|
|
||||||
var tempPath = fs.getTempPath();
|
|
||||||
var toSave = [ ];
|
|
||||||
|
|
||||||
try {
|
|
||||||
fs.makeDirectoryRecursive(tempPath);
|
|
||||||
var root = fs.join(tempPath, "foxx-apps-master/applications");
|
|
||||||
|
|
||||||
// remove any previous files in the directory
|
|
||||||
fs.listTree(root).forEach(function (file) {
|
|
||||||
if (file.match(/\.json$/)) {
|
|
||||||
try {
|
|
||||||
fs.remove(fs.join(root, file));
|
|
||||||
}
|
|
||||||
catch (ignore) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
fs.unzipFile(filename, tempPath, false, true);
|
|
||||||
|
|
||||||
if (! fs.exists(root)) {
|
|
||||||
throw new Error("'applications' directory is missing in foxx-apps-master, giving up");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var m = fs.listTree(root);
|
|
||||||
var reSub = /(.*)\.json$/;
|
|
||||||
var f, match, app, desc;
|
|
||||||
|
|
||||||
for (i = 0; i < m.length; ++i) {
|
|
||||||
f = m[i];
|
|
||||||
match = reSub.exec(f);
|
|
||||||
|
|
||||||
if (match === null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
app = fs.join(root, f);
|
|
||||||
|
|
||||||
try {
|
|
||||||
desc = JSON.parse(fs.read(app));
|
|
||||||
}
|
|
||||||
catch (err1) {
|
|
||||||
arangodb.printf("Cannot parse description for app '" + f + "': %s\n", String(err1));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
desc._key = match[1];
|
|
||||||
|
|
||||||
if (! desc.hasOwnProperty("name")) {
|
|
||||||
desc.name = match[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
toSave.push(desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (toSave.length > 0) {
|
|
||||||
var fishbowl = getFishbowlStorage();
|
|
||||||
|
|
||||||
db._executeTransaction({
|
|
||||||
collections: {
|
|
||||||
write: fishbowl.name()
|
|
||||||
},
|
|
||||||
action: function (params) {
|
|
||||||
var c = require("internal").db._collection(params.collection);
|
|
||||||
c.truncate();
|
|
||||||
|
|
||||||
params.apps.forEach(function(app) {
|
|
||||||
c.save(app);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
params: {
|
|
||||||
apps: toSave,
|
|
||||||
collection: fishbowl.name()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
arangodb.printf("Updated local repository information with %d application(s)\n",
|
|
||||||
toSave.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (tempPath !== undefined && tempPath !== "") {
|
|
||||||
try {
|
|
||||||
fs.removeDirectoryRecursive(tempPath);
|
|
||||||
}
|
|
||||||
catch (ignore) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief downloads the fishbowl repository
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
function updateFishbowl () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var url = buildGithubUrl(getFishbowlUrl());
|
|
||||||
var filename = fs.getTempFile("downloads", false);
|
|
||||||
var path = fs.getTempFile("zip", false);
|
|
||||||
|
|
||||||
try {
|
|
||||||
var result = download(url, "", {
|
|
||||||
method: "get",
|
|
||||||
followRedirects: true,
|
|
||||||
timeout: 30
|
|
||||||
}, filename);
|
|
||||||
|
|
||||||
if (result.code < 200 || result.code > 299) {
|
|
||||||
throwDownloadError("Github download from '" + url + "' failed with error code " + result.code);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateFishbowlFromZip(filename);
|
|
||||||
|
|
||||||
filename = undefined;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (filename !== undefined && fs.exists(filename)) {
|
|
||||||
fs.remove(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
fs.removeDirectoryRecursive(path);
|
|
||||||
}
|
|
||||||
catch (ignore) {
|
|
||||||
}
|
|
||||||
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Exports
|
/// @brief Exports
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
exports.updateFishbowl = updateFishbowl;
|
|
||||||
exports.listJson = listJson;
|
exports.listJson = listJson;
|
||||||
exports.getFishbowlStorage = getFishbowlStorage;
|
|
||||||
exports.availableJson = availableJson;
|
|
||||||
exports.buildGithubUrl = buildGithubUrl;
|
exports.buildGithubUrl = buildGithubUrl;
|
||||||
exports.repackZipFile = repackZipFile;
|
exports.repackZipFile = repackZipFile;
|
||||||
exports.processDirectory = processDirectory;
|
exports.processDirectory = processDirectory;
|
||||||
exports.processGithubRepository = processGithubRepository;
|
exports.processGithubRepository = processGithubRepository;
|
||||||
|
exports.validateAppName = validateAppName;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
|
|
|
@ -0,0 +1,468 @@
|
||||||
|
/*jslint continue:true */
|
||||||
|
/*global require, exports, module */
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Foxx application store
|
||||||
|
///
|
||||||
|
/// @file
|
||||||
|
///
|
||||||
|
/// DISCLAIMER
|
||||||
|
///
|
||||||
|
/// Copyright 2015 triagens GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
/// you may not use this file except in compliance with the License.
|
||||||
|
/// You may obtain a copy of the License at
|
||||||
|
///
|
||||||
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
///
|
||||||
|
/// Unless required by applicable law or agreed to in writing, software
|
||||||
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
/// See the License for the specific language governing permissions and
|
||||||
|
/// limitations under the License.
|
||||||
|
///
|
||||||
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||||
|
///
|
||||||
|
/// @author Dr. Frank Celler, Michael Hackstein
|
||||||
|
/// @author Copyright 2015, triAGENS GmbH, Cologne, Germany
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Global variables
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var checkedFishBowl = false;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Section imports
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var arangodb = require("org/arangodb");
|
||||||
|
var db = arangodb.db;
|
||||||
|
var download = require("internal").download;
|
||||||
|
var fs = require("fs");
|
||||||
|
var throwDownloadError = arangodb.throwDownloadError;
|
||||||
|
var utils = require("org/arangodb/foxx/manager-utils");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Section private functions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the fishbowl repository
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function getFishbowlUrl () {
|
||||||
|
return "arangodb/foxx-apps";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the fishbowl collection
|
||||||
|
///
|
||||||
|
/// this will create the collection if it does not exist. this is better than
|
||||||
|
/// needlessly creating the collection for each database in case it is not
|
||||||
|
/// used in context of the database.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var getFishbowlStorage = function() {
|
||||||
|
|
||||||
|
var c = db._collection('_fishbowl');
|
||||||
|
if (c === null) {
|
||||||
|
c = db._create('_fishbowl', { isSystem : true });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c !== null && ! checkedFishBowl) {
|
||||||
|
// ensure indexes
|
||||||
|
c.ensureFulltextIndex("description");
|
||||||
|
c.ensureFulltextIndex("name");
|
||||||
|
checkedFishBowl = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
};
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief comparator for applications
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var compareApps = function(l, r) {
|
||||||
|
var left = l.name.toLowerCase();
|
||||||
|
var right = r.name.toLowerCase();
|
||||||
|
|
||||||
|
if (left < right) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right < left) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief updates the fishbowl from a zip archive
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function updateFishbowlFromZip (filename) {
|
||||||
|
var i;
|
||||||
|
var tempPath = fs.getTempPath();
|
||||||
|
var toSave = [ ];
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.makeDirectoryRecursive(tempPath);
|
||||||
|
var root = fs.join(tempPath, "foxx-apps-master/applications");
|
||||||
|
|
||||||
|
// remove any previous files in the directory
|
||||||
|
fs.listTree(root).forEach(function (file) {
|
||||||
|
if (file.match(/\.json$/)) {
|
||||||
|
try {
|
||||||
|
fs.remove(fs.join(root, file));
|
||||||
|
}
|
||||||
|
catch (ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fs.unzipFile(filename, tempPath, false, true);
|
||||||
|
|
||||||
|
if (! fs.exists(root)) {
|
||||||
|
throw new Error("'applications' directory is missing in foxx-apps-master, giving up");
|
||||||
|
}
|
||||||
|
|
||||||
|
var m = fs.listTree(root);
|
||||||
|
var reSub = /(.*)\.json$/;
|
||||||
|
var f, match, app, desc;
|
||||||
|
|
||||||
|
for (i = 0; i < m.length; ++i) {
|
||||||
|
f = m[i];
|
||||||
|
match = reSub.exec(f);
|
||||||
|
|
||||||
|
if (match !== null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
app = fs.join(root, f);
|
||||||
|
|
||||||
|
try {
|
||||||
|
desc = JSON.parse(fs.read(app));
|
||||||
|
}
|
||||||
|
catch (err1) {
|
||||||
|
arangodb.printf("Cannot parse description for app '" + f + "': %s\n", String(err1));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc._key = match[1];
|
||||||
|
|
||||||
|
if (! desc.hasOwnProperty("name")) {
|
||||||
|
desc.name = match[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
toSave.push(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toSave.length > 0) {
|
||||||
|
var fishbowl = getFishbowlStorage();
|
||||||
|
|
||||||
|
db._executeTransaction({
|
||||||
|
collections: {
|
||||||
|
write: fishbowl.name()
|
||||||
|
},
|
||||||
|
action: function (params) {
|
||||||
|
var c = require("internal").db._collection(params.collection);
|
||||||
|
c.truncate();
|
||||||
|
|
||||||
|
params.apps.forEach(function(app) {
|
||||||
|
c.save(app);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
apps: toSave,
|
||||||
|
collection: fishbowl.name()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
arangodb.printf("Updated local repository information with %d application(s)\n",
|
||||||
|
toSave.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
if (tempPath !== undefined && tempPath !== "") {
|
||||||
|
try {
|
||||||
|
fs.removeDirectoryRecursive(tempPath);
|
||||||
|
}
|
||||||
|
catch (ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Section public functions
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the search result for FOXX applications
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var searchJson = function (name) {
|
||||||
|
|
||||||
|
var fishbowl = getFishbowlStorage();
|
||||||
|
|
||||||
|
if (fishbowl.count() === 0) {
|
||||||
|
arangodb.print("Repository is empty, please use 'update'");
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
var docs;
|
||||||
|
|
||||||
|
if (name === undefined || (typeof name === "string" && name.length === 0)) {
|
||||||
|
docs = fishbowl.toArray();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = name.replace(/[^a-zA-Z0-9]/g, ' ');
|
||||||
|
|
||||||
|
// get results by looking in "description" attribute
|
||||||
|
docs = fishbowl.fulltext("description", "prefix:" + name).toArray();
|
||||||
|
|
||||||
|
// build a hash of keys
|
||||||
|
var i;
|
||||||
|
var keys = { };
|
||||||
|
|
||||||
|
for (i = 0; i < docs.length; ++i) {
|
||||||
|
keys[docs[i]._key] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get results by looking in "name" attribute
|
||||||
|
var docs2= fishbowl.fulltext("name", "prefix:" + name).toArray();
|
||||||
|
|
||||||
|
// merge the two result sets, avoiding duplicates
|
||||||
|
for (i = 0; i < docs2.length; ++i) {
|
||||||
|
if (!keys.hasOwnProperty(docs2[i]._key)) {
|
||||||
|
docs.push(docs2[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return docs;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief searchs for an available FOXX applications
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var search = function (name) {
|
||||||
|
var docs = searchJson(name);
|
||||||
|
|
||||||
|
arangodb.printTable(
|
||||||
|
docs.sort(compareApps),
|
||||||
|
[ "name", "author", "description" ],
|
||||||
|
{
|
||||||
|
prettyStrings: true,
|
||||||
|
totalString: "%s application(s) found",
|
||||||
|
emptyString: "no applications found",
|
||||||
|
rename: {
|
||||||
|
name : "Name",
|
||||||
|
author : "Author",
|
||||||
|
description : "Description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns all available FOXX applications
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
function availableJson() {
|
||||||
|
var fishbowl = getFishbowlStorage();
|
||||||
|
var cursor = fishbowl.all();
|
||||||
|
var result = [];
|
||||||
|
var doc, maxVersion, versions, res;
|
||||||
|
|
||||||
|
while (cursor.hasNext()) {
|
||||||
|
doc = cursor.next();
|
||||||
|
|
||||||
|
maxVersion = "-";
|
||||||
|
versions = Object.keys(doc.versions);
|
||||||
|
versions.sort(module.compareVersions);
|
||||||
|
if (versions.length > 0) {
|
||||||
|
versions.reverse();
|
||||||
|
maxVersion = versions[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
res = {
|
||||||
|
name: doc.name,
|
||||||
|
description: doc.description || "",
|
||||||
|
author: doc.author || "",
|
||||||
|
latestVersion: maxVersion
|
||||||
|
};
|
||||||
|
|
||||||
|
result.push(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief updates the repository
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
var update = function() {
|
||||||
|
var url = utils.buildGithubUrl(getFishbowlUrl());
|
||||||
|
var filename = fs.getTempFile("downloads", false);
|
||||||
|
var path = fs.getTempFile("zip", false);
|
||||||
|
|
||||||
|
try {
|
||||||
|
var result = download(url, "", {
|
||||||
|
method: "get",
|
||||||
|
followRedirects: true,
|
||||||
|
timeout: 30
|
||||||
|
}, filename);
|
||||||
|
|
||||||
|
if (result.code < 200 || result.code > 299) {
|
||||||
|
throwDownloadError("Github download from '" + url + "' failed with error code " + result.code);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFishbowlFromZip(filename);
|
||||||
|
|
||||||
|
filename = undefined;
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
if (filename !== undefined && fs.exists(filename)) {
|
||||||
|
fs.remove(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.removeDirectoryRecursive(path);
|
||||||
|
}
|
||||||
|
catch (ignore) {
|
||||||
|
}
|
||||||
|
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief prints all available FOXX applications
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var available = function () {
|
||||||
|
var list = availableJson();
|
||||||
|
|
||||||
|
arangodb.printTable(
|
||||||
|
list.sort(compareApps),
|
||||||
|
[ "name", "author", "description", "latestVersion" ],
|
||||||
|
{
|
||||||
|
prettyStrings: true,
|
||||||
|
totalString: "%s application(s) found",
|
||||||
|
emptyString: "no applications found, please use 'update'",
|
||||||
|
rename: {
|
||||||
|
"name" : "Name",
|
||||||
|
"author" : "Author",
|
||||||
|
"description" : "Description",
|
||||||
|
"latestVersion" : "Latest Version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief info for an available FOXX application
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var info = function (name) {
|
||||||
|
utils.validateAppName(name);
|
||||||
|
|
||||||
|
var fishbowl = getFishbowlStorage();
|
||||||
|
|
||||||
|
if (fishbowl.count() === 0) {
|
||||||
|
arangodb.print("Repository is empty, please use 'update'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var desc;
|
||||||
|
|
||||||
|
try {
|
||||||
|
desc = fishbowl.document(name);
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
arangodb.print("No application '" + name + "' available, please try 'search'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
arangodb.printf("Name: %s\n", desc.name);
|
||||||
|
|
||||||
|
if (desc.hasOwnProperty('author')) {
|
||||||
|
arangodb.printf("Author: %s\n", desc.author);
|
||||||
|
}
|
||||||
|
|
||||||
|
var isSystem = desc.hasOwnProperty('isSystem') && desc.isSystem;
|
||||||
|
arangodb.printf("System: %s\n", JSON.stringify(isSystem));
|
||||||
|
|
||||||
|
if (desc.hasOwnProperty('description')) {
|
||||||
|
arangodb.printf("Description: %s\n\n", desc.description);
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = false;
|
||||||
|
var versions = Object.keys(desc.versions);
|
||||||
|
versions.sort(module.compareVersions);
|
||||||
|
|
||||||
|
versions.forEach(function (v) {
|
||||||
|
var version = desc.versions[v];
|
||||||
|
|
||||||
|
if (! header) {
|
||||||
|
arangodb.print("Versions:");
|
||||||
|
header = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version.type === "github") {
|
||||||
|
if (version.hasOwnProperty("tag")) {
|
||||||
|
arangodb.printf('%s: fetch github "%s" "%s"\n', v, version.location, version.tag);
|
||||||
|
}
|
||||||
|
else if (v.hasOwnProperty("branch")) {
|
||||||
|
arangodb.printf('%s: fetch github "%s" "%s"\n', v, version.location, version.branch);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
arangodb.printf('%s: fetch "github" "%s"\n', v, version.location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
arangodb.printf("\n");
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Section export public API
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
exports.available = available;
|
||||||
|
exports.availableJson = availableJson;
|
||||||
|
exports.getFishbowlStorage = getFishbowlStorage;
|
||||||
|
exports.search = search;
|
||||||
|
exports.searchJson = searchJson;
|
||||||
|
exports.update = update;
|
||||||
|
exports.info = info;
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- END-OF-FILE
|
||||||
|
// -----------------------------------------------------------------------------
|
|
@ -35,6 +35,7 @@ var errors = arangodb.errors;
|
||||||
var console = require("console");
|
var console = require("console");
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var utils = require("org/arangodb/foxx/manager-utils");
|
var utils = require("org/arangodb/foxx/manager-utils");
|
||||||
|
var store = require("org/arangodb/foxx/store");
|
||||||
|
|
||||||
var _ = require("underscore");
|
var _ = require("underscore");
|
||||||
|
|
||||||
|
@ -1732,22 +1733,6 @@ exports.fetchFromGithub = function (url, name, version) {
|
||||||
return "app:" + source.name + ":" + source.version;
|
return "app:" + source.name + ":" + source.version;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief updates the repository
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
exports.update = utils.updateFishbowl;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
///// @brief returns all available FOXX applications
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
exports.availableJson = function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
return utils.availableJson();
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///// @brief returns all installed FOXX applications
|
///// @brief returns all installed FOXX applications
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1758,16 +1743,6 @@ exports.listJson = function () {
|
||||||
return utils.listJson();
|
return utils.listJson();
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief returns the fishbowl collection
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
exports.getFishbowlStorage = function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
return utils.getFishbowlStorage();
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief initializes the Foxx apps
|
/// @brief initializes the Foxx apps
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -1837,6 +1812,19 @@ exports.initializeFoxx = function () {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Exports from foxx store module.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
exports.available = store.available;
|
||||||
|
exports.availableJson = store.availableJson;
|
||||||
|
exports.getFishbowlStorage = store.getFishbowlStorage;
|
||||||
|
exports.search = store.search;
|
||||||
|
exports.searchJson = store.searchJson;
|
||||||
|
exports.update = store.update;
|
||||||
|
exports.info = store.info;
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- END-OF-FILE
|
// --SECTION-- END-OF-FILE
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue