1 | var path = require('path');
|
2 | var util = require('util');
|
3 | var fs = require('fs');
|
4 | var request = require('request');
|
5 | var qs = require('querystring');
|
6 | var unzip = require('unzip');
|
7 | var walk = require('walk-promise');
|
8 | var md5 = require('md5');
|
9 | var archiver = require('archiver');
|
10 | var chalk = require('chalk');
|
11 | var argv = require('minimist')(process.argv.slice(2));
|
12 | var Tools = require('../lib/tools');
|
13 | var AccountManager = require('../lib/account');
|
14 |
|
15 | module.exports = ProjectManager;
|
16 |
|
17 | function ProjectManager() {}
|
18 |
|
19 | var packs = {};
|
20 | ProjectManager.config = function() {
|
21 | var configPath = path.resolve('project.json');
|
22 | if (!fs.existsSync(configPath)) {
|
23 | console.log("not in a aics project ,frist run aics project init [name] ");
|
24 | process.exit(1);
|
25 | }
|
26 | var json = require(configPath);
|
27 |
|
28 | if (!json.prototype) {
|
29 | console.log("project use some prototype");
|
30 | process.exit(1);
|
31 | }
|
32 |
|
33 | if (!json.name) {
|
34 | console.log("project need a name");
|
35 | process.exit(1);
|
36 | }
|
37 |
|
38 | if (!json.version) {
|
39 | console.log("project need a version");
|
40 | process.exit(1);
|
41 | }
|
42 |
|
43 | if (!json.packages) {
|
44 | console.log("project some packages");
|
45 | process.exit(1);
|
46 | }
|
47 |
|
48 | return json;
|
49 | }
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | ProjectManager.initProject = function(args) {
|
61 | fs.stat('.aics', function(err, stats) {
|
62 | if (!stats) {
|
63 | fs.mkdir(".aics");
|
64 | console.log('在当前目录创建.aics文件夹成功.\n')
|
65 | }
|
66 | var project = require('json/project.json');
|
67 | project.name = AccountManager.username + ":" + argv.p;
|
68 | fs.writeFile('.aics/project.json', JSON.stringify(project, null, 2), 'utf8', function(err) {
|
69 | if (err) {
|
70 | console.log('写入 .aics/project.json 错误')
|
71 | };
|
72 | console.log('创建 .aics/project.json 成功.')
|
73 | fs.writeFile('.aics/packages.json', "{}", 'utf8', function(err) {
|
74 | if (err) {
|
75 | console.log('写入 package.json 错误')
|
76 | };
|
77 | console.log('创建 .aics/packages.json 成功.')
|
78 | });
|
79 | fs.writeFile('README.md', "## " + argv.p, 'utf8', function(err) {
|
80 | if (err) {
|
81 | console.log('写入 README.md 错误')
|
82 | } else {
|
83 | console.log('创建 README.md 成功.')
|
84 | }
|
85 | });
|
86 | });
|
87 | })
|
88 | }
|
89 | ProjectManager.initWithSample = function(example) {
|
90 | var param = {
|
91 | "project": example
|
92 | };
|
93 | if (example.split(":").length > 1) {
|
94 | name = argv.e.split(":").pop();
|
95 | } else {
|
96 | console.log("\n项目名输入错误.\n");
|
97 | return;
|
98 | }
|
99 | request(process.env.AICS_HOST + "/project/info?" + qs.stringify(param), function(error, response, body) {
|
100 | console.log(body)
|
101 | body = JSON.parse(body);
|
102 | try {
|
103 | fs.stat('.aics', function(err, stats) {
|
104 | if (!stats) {
|
105 | fs.mkdir(".aics");
|
106 | }
|
107 | })
|
108 | } catch (e) {
|
109 | fs.mkdir(".aics");
|
110 | }
|
111 |
|
112 | fs.writeFile('README.md', body.documentation, 'utf8', function(err) {
|
113 | if (err) {
|
114 | console.log('写入 README.md 错误')
|
115 | } else {
|
116 | body.documentation = "README.md";
|
117 | fs.writeFile('.aics/project.json', JSON.stringify(body, null, 2), 'utf8', function(err) {
|
118 | if (err) {
|
119 | console.log('写入 .aics/project.json 错误');
|
120 | } else {
|
121 |
|
122 | }
|
123 | });
|
124 | console.log('\n' + chalk.green.bold('Success.') + '\n');
|
125 | }
|
126 | });
|
127 | });
|
128 | }
|
129 | ProjectManager.update = function(configname) {
|
130 | if (!configname) {
|
131 | var config = require(path.resolve(".aics") + "/project.json");
|
132 | console.log("更新项目依赖的代码包...");
|
133 | for (var pname in config.packages) {
|
134 | queryPackage(pname, config.packages[pname]);
|
135 | }
|
136 |
|
137 | } else if (configname == "--all") {
|
138 |
|
139 |
|
140 | walk(path.resolve(".aics")).then(function(files) {
|
141 | for (var i = 0; i < files.length; i++) {
|
142 | var file = files[i];
|
143 | if (file.name.indexOf(".depot.json") > 0) {
|
144 |
|
145 | console.log("读取包配置文件: .aics/" + file.name);
|
146 | var config = Tools.projectConfig(".aics/" + file.name);
|
147 | if (config.dependencies) {
|
148 | for (var pname in config.dependencies) {
|
149 | queryPackage(pname, config.dependencies[pname]);
|
150 | }
|
151 | }
|
152 | }
|
153 |
|
154 | }
|
155 | });
|
156 |
|
157 |
|
158 | } else {
|
159 |
|
160 | configname = configname + ".depot.json";
|
161 | var config = Tools.projectConfig(".aics/" + configname);
|
162 | if (config.dependencies) {
|
163 | console.log("读取包配置文件: .aics/" + configname);
|
164 | for (var pname in config.dependencies) {
|
165 | queryPackage(pname, config.dependencies[pname]);
|
166 | }
|
167 | }
|
168 | }
|
169 | }
|
170 | ProjectManager.remove = function(name) {
|
171 |
|
172 | }
|
173 | ProjectManager.add = function(name) {
|
174 | var projConf;
|
175 | if (!name) {
|
176 | console.log(" 在 add 命令后添加您要添加的代码包名称。可以在http://codedepot.fami2u.com 寻找感兴趣的代码包");
|
177 | return;
|
178 | }
|
179 |
|
180 | var config = Tools.getAics();
|
181 | if (typeof config[name] == "string") {
|
182 | console.log(chalk.green(name) + " has been Installd.");
|
183 | return;
|
184 | }
|
185 |
|
186 | var packageinfo = name.split("@");
|
187 | var param = {
|
188 | name: packageinfo.shift(),
|
189 | version: packageinfo.pop() || ""
|
190 | };
|
191 | request(process.env.AICS_HOST + "/package/info?" + qs.stringify(param), function(error, response, body) {
|
192 | if (body == "NONE") {
|
193 | console.log("Not Found: " + chalk.red(name));
|
194 | } else {
|
195 | var result = JSON.parse(body);
|
196 | config = Tools.projectConfig(path.resolve(".aics/project.json"));
|
197 | config.packages[name] = result.version;
|
198 |
|
199 | fs.writeFile(path.resolve(".aics/project.json"), JSON.stringify(config, null, 2), 'utf8', function(err, res) {
|
200 | setupPackage(result);
|
201 | });
|
202 |
|
203 | }
|
204 | });
|
205 |
|
206 |
|
207 | }
|
208 |
|
209 | ProjectManager.publish = function(params) {
|
210 | var config = require(path.resolve('.aics/project.json'));
|
211 | if (!configCheck(config)) {
|
212 | console.log(chalk.red.bold("配置文件出错."));
|
213 | return;
|
214 | }
|
215 | fs.readFile(path.resolve(config.documentation), 'utf8', function(err, res) {
|
216 | config.documentation = res;
|
217 | config.creater = AccountManager.get().secret;
|
218 | var r = request.post(process.env.AICS_HOST + '/project/create?' + qs.stringify(config), function(err, httpResponse, body) {
|
219 | console.log(body);
|
220 | });
|
221 | })
|
222 | }
|
223 | queryPackage = function(name, version) {
|
224 | var _aics = Tools.getAics();
|
225 | if (_aics[name] == version) {
|
226 | console.log("代码包: " + name + "@" + version + " 已安装");
|
227 | } else {
|
228 | request(process.env.AICS_HOST + "/package/info?" + qs.stringify({
|
229 | name: name,
|
230 | version: version
|
231 | }), function(error, response, body) {
|
232 | if (body == "NONE") {
|
233 | console.log("未发现代码包: " + name);
|
234 | } else {
|
235 | var result = JSON.parse(body);
|
236 | var name = result.name;
|
237 | var version = result.version;
|
238 | setupPackage(result);
|
239 | for (var pname in result.dependencies) {
|
240 | queryPackage(pname, result.dependencies[pname]);
|
241 | }
|
242 | }
|
243 | });
|
244 |
|
245 | }
|
246 | }
|
247 | setupPackage = function(packages) {
|
248 | console.log("Downloading " + packages.name + "@" + packages.version + "...");
|
249 | var packagePath = packages.name.split(':');
|
250 |
|
251 | var tmppath = Tools.mkdir(".aics/tmp" + "/" + packagePath.join('/') + "@" + packages.version);
|
252 | if (!packages.url || packages.url.indexOf('http://') < 0) {
|
253 | console.log('请求URL不合法')
|
254 | return;
|
255 | }
|
256 | request(packages.url)
|
257 | .on('error', function(err) {
|
258 | console.log(err)
|
259 | })
|
260 | .pipe(fs.createWriteStream(tmppath + "/build.zip"))
|
261 | .on('close', function() {
|
262 | fs.createReadStream(tmppath + "/build.zip")
|
263 | .pipe(unzip.Extract({
|
264 | path: tmppath
|
265 | }))
|
266 | .on("close", function() {
|
267 | var rootPath = path.resolve('.');
|
268 |
|
269 | fs.unlinkSync(tmppath + "/packages");
|
270 | walk(tmppath).then(function(files) {
|
271 | for (var i = 0; i < files.length; i++) {
|
272 | var file = files[i];
|
273 | var filename = file.name;
|
274 | if ((filename.indexOf(".") != 0) && (filename.indexOf("build.zip") == -1)) {
|
275 | exportFiles(packages, file, tmppath);
|
276 | }
|
277 | }
|
278 | console.log("已写入代码包文件: " + packages.name.replace("$", ":") + "@" + packages.version);
|
279 | Tools.setAics(packages.name, packages.version);
|
280 | });
|
281 | });
|
282 | });
|
283 | }
|
284 |
|
285 | exportFiles = function(packages, file, tmppath) {
|
286 | var filename = file.name;
|
287 | var fileroot = file.root;
|
288 | var filepath = path.resolve(fileroot.replace(tmppath, "./"));
|
289 | Tools.mkdir(filepath);
|
290 |
|
291 | if (fs.existsSync(filepath + "/" + filename)) {
|
292 | var org = fs.readFileSync(file.root + "/" + filename)
|
293 | var orgmd5 = md5(org);
|
294 | var tar = fs.readFileSync(filepath + "/" + filename)
|
295 | var tarmd5 = md5(tar);
|
296 | if (tarmd5 != orgmd5) {
|
297 | fs.writeFile(filepath + "/" + filename + "@" + packages.version, org, function(err) {
|
298 |
|
299 |
|
300 | if (err) {
|
301 | console.log(err);
|
302 | } else {
|
303 | console.log("代码包中的文件于本地不一致: " + filepath + "/" + filename + " in " + packages.name + "@" + packages.version);
|
304 | }
|
305 | });
|
306 |
|
307 | } else {
|
308 |
|
309 |
|
310 | }
|
311 | } else {
|
312 | fs.createReadStream(file.root + "/" + filename)
|
313 | .pipe(fs.createWriteStream(filepath + "/" + filename))
|
314 | .on("close", function() {
|
315 |
|
316 |
|
317 | });
|
318 | }
|
319 | }
|
320 | configCheck = function(config) {
|
321 | if (!config.stack) {
|
322 | console.log("project belong to some stack");
|
323 | return false;
|
324 | }
|
325 | if (!config.name) {
|
326 | console.log("project need a name");
|
327 | return false;
|
328 | }
|
329 | if (!config.version) {
|
330 | console.log("project need a version");
|
331 | return false;
|
332 | }
|
333 | if (!config.files) {
|
334 | console.log("project need a files list");
|
335 | return false;
|
336 | }
|
337 |
|
338 | return true;
|
339 | }
|