1 | var Q = require('q');
|
2 | var fs = require('fs-extra');
|
3 | var path = require('path');
|
4 | var _ = require('lodash');
|
5 | var npmi = require('npmi');
|
6 | var npm = require('npm');
|
7 | var tmp = require('tmp');
|
8 | var color = require('bash-color');
|
9 | var parsedArgv = require('optimist').argv;
|
10 |
|
11 | var config = require('./config');
|
12 | var tags = require('./tags');
|
13 |
|
14 |
|
15 | function listVersions() {
|
16 | var folders = fs.readdirSync(config.VERSIONS_ROOT);
|
17 | var latest = null;
|
18 |
|
19 | return _.chain(folders)
|
20 | .map(function(tag) {
|
21 |
|
22 | if (!tags.isValid(tag)) return null;
|
23 |
|
24 |
|
25 | var versionFolder = path.resolve(config.VERSIONS_ROOT, tag);
|
26 | var stat = fs.lstatSync(versionFolder);
|
27 | var pkg;
|
28 |
|
29 | try {
|
30 | pkg = require(path.resolve(versionFolder, 'package.json'));
|
31 | } catch(e) {
|
32 | return null;
|
33 | }
|
34 |
|
35 |
|
36 | if (pkg.name != 'gitbook') return null;
|
37 |
|
38 | return {
|
39 |
|
40 | name: tag,
|
41 |
|
42 |
|
43 | version: pkg.version,
|
44 |
|
45 |
|
46 | path: versionFolder,
|
47 |
|
48 |
|
49 | link: stat.isSymbolicLink()? fs.readlinkSync(versionFolder) : null,
|
50 |
|
51 |
|
52 | tag: tags.getTag(pkg.version)
|
53 | };
|
54 | })
|
55 | .compact()
|
56 |
|
57 |
|
58 | .sort(function(a, b) {
|
59 | return tags.sort(a.version, b.version);
|
60 | })
|
61 | .value();
|
62 | }
|
63 |
|
64 |
|
65 | function versionRoot(version) {
|
66 | return path.resolve(config.VERSIONS_ROOT, version);
|
67 | }
|
68 |
|
69 |
|
70 | function resolveVersion(condition) {
|
71 | var versions = listVersions();
|
72 | var version = _.chain(versions)
|
73 | .find(function(v) {
|
74 | return tags.satisfies(v.name, condition);
|
75 | })
|
76 | .value();
|
77 |
|
78 | if (!version) return Q.reject(new Error('No version match: '+condition));
|
79 | return Q(version);
|
80 | }
|
81 |
|
82 |
|
83 | function removeVersion(version) {
|
84 | if (!version) return Q.reject(new Error('No version specified'));
|
85 | var outputFolder = versionRoot(version);
|
86 |
|
87 | return Q.nfcall(fs.lstat.bind(fs), outputFolder)
|
88 | .then(function(stat) {
|
89 | if (stat.isSymbolicLink()) {
|
90 | return Q.nfcall(fs.unlink.bind(fs), outputFolder);
|
91 | }
|
92 | return Q.nfcall(fs.remove.bind(fs), outputFolder);
|
93 | });
|
94 | }
|
95 |
|
96 |
|
97 | function loadVersion(version) {
|
98 | return Q(_.isString(version)? resolveVersion(version) : version)
|
99 | .then(function(resolved) {
|
100 | var gitbook;
|
101 |
|
102 | try {
|
103 | gitbook = require(resolved.path);
|
104 | } catch (err) {
|
105 | console.log(color.red('Error loading version '+resolved.tag+': '+(err.stack || err.message || err)));
|
106 | return null;
|
107 | }
|
108 |
|
109 | if (!gitbook) throw new Error('GitBook Version '+resolved.tag+' is corrupted');
|
110 | return gitbook;
|
111 | });
|
112 | }
|
113 |
|
114 |
|
115 | function linkVersion(name, folder) {
|
116 | if (!name) return Q.reject(new Error('Require a name to represent this GitBook version'));
|
117 | if (!folder) return Q.reject(new Error('Require a folder'));
|
118 | var outputFolder = versionRoot(name);
|
119 |
|
120 | return Q.nfcall(fs.symlink.bind(fs), folder, outputFolder);
|
121 | }
|
122 |
|
123 | module.exports = {
|
124 | load: loadVersion,
|
125 | resolve: resolveVersion,
|
126 | versions: listVersions,
|
127 | remove: removeVersion,
|
128 | link: linkVersion
|
129 | };
|