Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: df34033d39
Fetching contributors…

Cannot retrieve contributors at this time

executable file 454 lines (347 sloc) 13.679 kb
#!/usr/bin/env node
var mod_root = require('path').normalize(__dirname + '/../');
var root = process.cwd() + '/';
var eol = require('os').platform() == 'win32' ? '\r\n' : '\n';
var Path = require('path');
var Fs = require('fs');
var spawn = require('child_process').spawn;
var Async = require('async');
var request = require('request');
var mkdir = require('mkdirp');
var colors = require('colors');
var copy = require('../lib/utils').copy;
var rand_str = require('../lib/utils').rand_str;
var load = require('../lib/utils').load;
var remove = require('../lib/utils').remove;
var check = require('../lib/utils').validator;
var zlib = require('zlib');
var tar = require('tar');
var gzip = zlib.createUnzip();
var semver = require('semver');
var info = require(mod_root +'package.json');
var modules = require(mod_root +'modules.json');
var App = require('commander');
App.version(info.version);
var Err = function(message) {
console.log('\n', message);
process.exit();
}
App.command('modules')
.description('list all available modules')
.action(function() {
var pack;
var total = 0;
try {
pack = require(root +'package.json').katana;
} catch(error) {}
for (var name in modules) {
total++;
var module = modules[name];
console.log('\n#'+ total, name, '-', module.description);
console.log(' author:', module.author.name, '<'+ module.author.email +'>');
console.log(' tags:', module.tags.length ? module.tags.join(' ') : 'no tags, download master branch');
if (pack !== undefined) {
var installed = pack.modules[name] !== undefined;
var enabled = pack.modules[name]!==undefined && pack.modules[name].enabled===true;
console.log(' installed:', installed ? 'true'.green : 'false'.yellow, ' enabled:', enabled ? 'true'.green : 'false'.yellow);
}
}
if (!total) {
console.log('There are no modules available.');
}
});
App.command('update')
.description('update modules list and info')
.action(function() {
var url = 'https://raw.github.com/Shogun147/Katana/master/modules.json';
request(url).on('response', function(response) {
if (response.statusCode !== 200 && response.statusCode !== 304) {
return Err('Error: url not found or error while downloading it.');
}
}).pipe(Fs.createWriteStream(mod_root + 'modules.json')).on('error', function(error) {
Err(error);
}).on('error', function(error) {
Err(error);
}).on('end', function() {
console.log('Done! Run "katana modules" to view updated modules list.');
process.exit();
});
});
App.command('search <contain>')
.description('search modules')
.action(function(contain) {
var pack;
var total = 0;
try {
pack = require(root +'package.json').katana;
} catch(error) {}
for (var name in modules) {
var module = modules[name];
var regexp = new RegExp(contain, 'ig');
if (regexp.test(module.name) || regexp.test(module.description)) {
total++;
console.log('#'+ total, name, '-', module.description);
console.log(' author:', module.author.name, '<'+ module.author.email +'>');
console.log(' tags:', module.tags.length ? module.tags.join(' ') : 'no tags, download master branch');
if (pack !== undefined) {
var installed = pack.modules[name] !== undefined;
var enabled = pack.modules[name]!==undefined && pack.modules[name].enabled===true;
console.log(' installed:', installed ? 'true'.green : 'false'.yellow, ' enabled:', enabled ? 'true'.green : 'false'.yellow);
}
}
}
if (!total) {
console.log(' There are no modules that match your search request.');
}
});
// name@version - installs from modules.json registry, optional version
// name username:name@version - install from github username and repo-name, optional version
// name url - install as name from url
App.command('install <name> [url]')
.description('install or reinstall application module')
.action(function(name, url) {
var ProgressBar = require('progress');
var Bar;
var username, version;
if ((!check(url, 'isUrl') || !url) && name.indexOf('@') !== -1) {
name = name.split('@');
version = name[1];
name = name[0];
if (!semver.valid(version)) {
return Err('Error:'.red, ' invalid version!');
}
}
if (url && !check(url, 'isUrl')) {
if (url.indexOf(':') === -1) {
return Err('Error:'.red, ' invalid url or github username:repository!');
}
var repository = url.split(':');
username = repository[0];
repository = repository[1];
if (!repository) {
return Err('Error: invalid repository name!');
}
if (repository.indexOf('@') !== -1) {
version = repository.split('@')[1];
repository = repository.split('@')[0];
if (!semver.valid(version)) {
return Err('Error: invalid version!');
}
}
url = 'https://github.com/'+ username +'/'+ repository +'/tarball/'+ (version || 'master');
}
check_installed(name, function(ok, exists) {
if(!ok) { return process.exit(); }
if (!username && !url && !modules[name]) {
return Err('Error: Module ['+ name +'] not found!')
}
if (!username && !url) {
var module = modules[name];
if (version && module.tags.indexOf(version) === -1) {
return Err('Error: there\'s no '+ version +' version for module ['+ name +']');
}
if (!version && module.tags.length) {
version = module.tags.pop();
}
url = module.url ? module.url + (version || 'master') : 'https://github.com/'+ module.github.username +'/'+ module.github.repository +'/tarball/'+ (version || 'master');
}
console.log(' name: ', name);
console.log(' version: ', version);
console.log('username: ', username);
console.log(' url: ', url);
mkdir(root + 'temp/modules/'+ name, 0777, function(error) {
if (error) { return Err('Error: could not create temporary directory.\n'+ error); }
request({ url: url })
.on('response', function(response) {
if (response.statusCode !== 200 && response.statusCode !== 304) {
this.abort();
return Err('Error: module not found! Server responded with status code: '+ response.statusCode);
}
if (response.headers['content-type'] !== 'application/x-gzip') {
this.abort();
return Err('Error: the server should respond with content-type application/x-gzip, '+ response.headers['content-type'] +' given.');
}
var length = parseInt(response.headers['content-length'], 10);
Bar = new ProgressBar('\n downloading [:bar] :percent :etas', {
complete: '=',
incomplete: ' ',
width: 40,
total: length
});
}).on('data', function(chunk) {
if (this._aborted) { return; }
Bar.tick(chunk.length);
}).pipe(zlib.createUnzip()).on('error', function(error) {
Err('Error: \n'+ error);
}).pipe(tar.Extract({ path: root +'temp/modules/'+ name })).on('error', function(error) {
Err('Error: \n'+ error);
}).on('end', function() {
Fs.readdir(root +'temp/modules/'+ name, function(error, items) {
if (error || !items.length) { return Err('Error: '+ (error ? '\n'+error : 'module extracting failed!')); }
var tmp = items[0];
var is_file = false;
Fs.readdir(root +'temp/modules/'+ name +'/'+ tmp, function(error, items) {
var pending = items.length;
Async.series([
function(callback) {
if (pending === 1) {
var item = items[0];
is_file = true;
copy(root +'temp/modules/'+ name +'/'+ tmp +'/'+ item, root +'modules/'+ item, function(error) {
callback(error);
});
} else {
Fs.mkdir(root +'modules/'+ name, 0777, function(error) {
if (error) { return callback(error); }
items.forEach(function(item) {
copy(root +'temp/modules/'+ name +'/'+ tmp +'/'+ item, root +'modules/'+ name +'/'+ item, function(error) {
if (error) { console.log(error); }
if (!--pending) {
callback();
}
});
});
});
}
},
function(callback) {
remove(root +'temp/modules/'+ name, function(error) {
if (error) { console.log('Warning:'.magento, 'could not remove temporary directory.'); }
callback();
});
},
function(callback) {
if (is_file) { return callback(); }
Fs.readdir(root +'modules/'+ name +'/hooks', function(error, hooks) {
if (error) { return callback(); }
var pending = hooks.length;
if (!pending) { return callback(); }
hooks.forEach(function(hook) {
Fs.chmod(root +'modules/'+ name +'/hooks/'+ hook, '+x', function(error) {
if (error) { console.log('Warning:'.magento, 'could not make hook "'+ hook +'" executable.'); }
if (!--pending) {
callback();
}
});
});
});
},
function(callback) {
run_hook('install', name, function(error) {
if (error) { console.log('Error while running install hook:\n', error); }
callback();
});
}
], function(error) {
if (error) {
return Err(error);
}
var pack = require(root +'package.json');
var v;
try {
var v = require(root +'modules/'+ name +'/package.json').version;
} catch(error) {}
pack.katana.modules[name] = {
version: v || version || null,
enabled: false
}
Fs.writeFile(root +'package.json', JSON.stringify(pack, null, 2), function(error) {
console.log('\nModule "'+ name +'" now installed! Run "katana module enable '+ name +'" to enable it.');
process.exit();
});
});
});
});
});
});
});
});
function check_installed(name, callback) {
Fs.exists(root +'modules/'+ name, function(exists) {
if (!exists) {
return callback(true, false);
}
App.confirm('Module '+ name +' already installed, did you want to continue and rewrite old one? [Yes|No] ', function(ok) {
remove(root +'modules/'+ name, function(error) {
if (error) {
return Err('Error:'.red, 'could not remove existing module directory!');
}
callback(ok, true);
});
});
});
}
App.command('enable <name>')
.description('enable module')
.action(function(module) {
run_hook('enable', module, function(error) {
if (error) { return Err(error); }
var pack = require(root +'package.json');
pack.katana.modules[module].enabled = true;
Fs.writeFile(root +'package.json', JSON.stringify(pack, null, 2), function(error) {
if (error) { return Err(error); }
console.log('Done! Module "'+ module +'" now', 'enabled'.green, '!');
});
});
});
App.command('disable <name>')
.description('disable module')
.action(function(module) {
run_hook('disable', module, function(error) {
if (error) { return Err(error); }
var pack = require(root +'package.json');
pack.katana.modules[module].enabled = false;
Fs.writeFile(root +'package.json', JSON.stringify(pack, null, 2), function(error) {
if (error) { return Err(error); }
console.log('Done! Module "'+ module +'" now', 'disabled'.yellow, '!');
});
});
});
App.command('uninstall <name>')
.description('remove module')
.action(function(module) {
run_hook('uninstall', module, function(error) {
if (error) { return Err(error); }
var path = root +'modules/'+ module;
if (Fs.existsSync(path +'.js')) {
path += '.js';
}
remove(path, function(error) {
if (error) { return Err(error); }
var pack = require(root +'package.json');
delete pack.katana.modules[module];
Fs.writeFile(root +'package.json', JSON.stringify(pack, null, 2), function(error) {
if (error) { return Err(error); }
console.log('Done! Module "'+ module +'"', 'removed'.red, '!');
});
})
});
});
var run_hook = function(name, module, callback) {
Fs.exists(root +'modules/'+ module +'/hooks/'+ name +'.js', function(exists) {
if (!exists) { return callback(); }
var hook = spawn(root +'modules/'+ module +'/hooks/'+ name +'.js', [], {
cwd: root,
stdio: 'inherit'
});
hook.on('exit', function(code) {
if (code) {
return callback('Something goes wrong. Hook exited with code: '+ code);
}
callback();
});
try {
['SIGTERM', 'SIGINT', 'SIGHUP', 'SIGQUIT'].forEach(function(signal) {
process.on(signal, function() {
if (hook) {
hook.kill(signal);
}
process.exit();
});
});
} catch(e) {
// callback(e);
}
});
}
App.parse(process.argv);
Jump to Line
Something went wrong with that request. Please try again.