forked from skygragon/leetcode-cli
-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathplugin.js
127 lines (104 loc) · 2.94 KB
/
plugin.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
var fs = require('fs');
var path = require('path');
var _ = require('underscore');
var request = require('request');
var h = require('./helper');
var config = require('./config');
var log = require('./log');
function Plugin(id, name, ver, desc, deps) {
this.id = id;
this.name = name;
this.ver = ver || 'default';
this.desc = desc;
this.enabled = true;
// only need deps for current platform
this.deps = _.chain(deps || [])
.filter(function(x) { return x.indexOf(':') < 0 || x.indexOf(':' + process.platform) > 0; })
.map(function(x) { return x.split(':')[0]; })
.value();
}
Plugin.prototype.init = function() {
this.config = config.plugins[this.name] || {};
this.next = null;
};
Plugin.prototype.setNext = function(next) {
Object.setPrototypeOf(this, next);
this.next = next;
};
Plugin.prototype.install = function(cb) {
if (this.deps.length === 0) return cb();
var cmd = 'npm install --save ' + this.deps.join(' ');
log.debug(cmd);
var spin = h.spin(cmd);
require('child_process').exec(cmd, {cwd: h.getCodeDir()}, function() {
spin.stop();
return cb();
});
};
Plugin.prototype.help = function() {};
Plugin.plugins = [];
Plugin.init = function(head) {
var plugins = [];
h.getCodeDirData('lib/plugins').forEach(function(f) {
var p = f.data;
if (!p) return;
p.file = f.file;
if (f.name[0] === '.') p.enabled = false;
log.trace('found plugin: ' + p.name + '=' + p.ver);
if (p.enabled) {
p.init();
log.trace('inited plugin: ' + p.name);
} else {
log.trace('skipped plugin: ' + p.name);
}
plugins.push(p);
});
// chain the plugins together
// the one has bigger `id` comes first
plugins = _.sortBy(plugins, function(p) {
return -p.id;
});
var last = head;
plugins.forEach(function(p) {
if (!p.enabled) return;
last.setNext(p);
last = p;
});
Plugin.plugins = plugins;
};
Plugin.copy = function(src, cb) {
// FIXME: remove local file support?
if (path.extname(src) !== '.js') {
src = config.sys.urls.plugin.replace('$name', src);
}
var dst = h.getPluginFile(src);
var srcstream = src.startsWith('https://') ? request(src) : fs.createReadStream(src);
srcstream.on('response', function(resp) {
if (resp.statusCode !== 200)
srcstream.emit('error', 'HTTP Error: ' + resp.statusCode);
});
srcstream.on('error', function(e) {
spin.stop();
fs.unlinkSync(dst);
return cb(e);
});
var dststream = fs.createWriteStream(dst);
dststream.on('close', function() {
spin.stop();
return cb(null, dst);
});
log.debug('copying from ' + src);
var spin = h.spin('Downloading ' + src);
srcstream.pipe(dststream);
};
Plugin.install = function(name, cb) {
Plugin.copy(name, function(e, fullpath) {
if (e) return log.error(e);
log.debug('copied to ' + fullpath);
var plugin = require(fullpath);
plugin.install(function() {
return cb(null, plugin);
});
});
};
module.exports = Plugin;