forked from skygragon/leetcode-cli
-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathplugin.js
129 lines (106 loc) · 2.97 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
128
129
'use strict';
var cp = require('child_process');
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.includes(':') || x.includes(':' + process.platform); })
.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);
cp.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;