1 | var path = require('path');
|
2 | var _ = require('underscore');
|
3 | var Source = require('./sources/source');
|
4 | var Command = require('./command');
|
5 | var fs = require('fs');
|
6 | var fstream = require('fstream');
|
7 | var wrench = require('wrench');
|
8 | var spawn = require('child_process').spawn;
|
9 | var exec = require('child_process').exec;
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | Meteor = function(config) {
|
18 |
|
19 | config = config || {};
|
20 | this.defaultMeteor = (! _.include(_.keys(config), 'git'));
|
21 |
|
22 | if (this.defaultMeteor) {
|
23 | this.prepared = true
|
24 | } else {
|
25 | config.git = config.git || 'https://github.com/meteor/meteor.git';
|
26 | config.keepGitDir = true;
|
27 |
|
28 |
|
29 | var root = Meteor.installRoot();
|
30 |
|
31 | this.source = Source.prepare(root, config);
|
32 |
|
33 |
|
34 | this.prepared = fs.existsSync(this.source.path);
|
35 | }
|
36 | };
|
37 |
|
38 |
|
39 | Meteor.prototype.prepare = function(buildDevBundle, fn) {
|
40 | var self = this;
|
41 |
|
42 | if (_.isFunction(buildDevBundle))
|
43 | fn = buildDevBundle;
|
44 |
|
45 |
|
46 | if (self.defaultMeteor)
|
47 | return fn();
|
48 |
|
49 | self.source.fetch(function() {
|
50 | self.install(buildDevBundle, fn);
|
51 | }, 'Meteor');
|
52 | };
|
53 |
|
54 | Meteor.prototype.install = function(buildDevBundle, fn) {
|
55 | var self = this;
|
56 |
|
57 | if (_.isFunction(buildDevBundle))
|
58 | fn = buildDevBundle;
|
59 |
|
60 | self.prepared = true;
|
61 |
|
62 |
|
63 | var dev_bundle = path.join(self.source.path, 'dev_bundle');
|
64 |
|
65 | if (!fs.existsSync(dev_bundle)) {
|
66 |
|
67 | if (buildDevBundle) {
|
68 | console.log('Building Meteor development bundle');
|
69 | var generate = spawn('./scripts/generate-dev-bundle.sh', [], {cwd: self.source.path});
|
70 |
|
71 | generate.stdout.pipe(process.stdout);
|
72 | generate.stderr.pipe(process.stderr);
|
73 | generate.on('exit', fn);
|
74 |
|
75 | } else {
|
76 |
|
77 | console.log('Downloading Meteor development bundle');
|
78 | var meteor = spawn('./meteor', ['--help'], {cwd: self.source.path});
|
79 |
|
80 |
|
81 | meteor.stderr.pipe(process.stderr);
|
82 | meteor.on('exit', fn);
|
83 | }
|
84 | } else {
|
85 | fn();
|
86 | }
|
87 | };
|
88 |
|
89 |
|
90 | Meteor.prototype.ensurePrepared = function(fn) {
|
91 | if (this.prepared) {
|
92 | fn();
|
93 | } else {
|
94 | this.prepare(fn);
|
95 | }
|
96 | };
|
97 |
|
98 | Meteor.prototype._executable = function() {
|
99 | var self = this;
|
100 |
|
101 | if (self.defaultMeteor) {
|
102 | return 'meteor';
|
103 | } else {
|
104 | return path.join(self.source.packagePath(), 'meteor');
|
105 | }
|
106 | }
|
107 |
|
108 |
|
109 | Meteor.prototype.execute = function(args, package_dir, fn) {
|
110 | var self = this;
|
111 |
|
112 | if (_.isFunction(package_dir)) {
|
113 | fn = package_dir;
|
114 | package_dir = null;
|
115 | }
|
116 |
|
117 | self.ensurePrepared(function() {
|
118 | Command.spawn(self._executable(), args, package_dir, fn);
|
119 | });
|
120 | };
|
121 |
|
122 | Meteor.prototype.isUsing = function(packageName, fn) {
|
123 | var self = this;
|
124 |
|
125 | Command.exec(self._executable(), ['list', '--using'], function(error, packages) {
|
126 | var packageNames = packages.split('\n');
|
127 |
|
128 | var regExp = new RegExp('^\w*' + packageName + '\w*$');
|
129 | fn(_.any(packageNames, function(pn) { return regExp.exec(pn); }));
|
130 | });
|
131 | }
|
132 |
|
133 | Meteor.prototype.hasPackage = function(pkgName, fn) {
|
134 | var self = this;
|
135 |
|
136 | if (self.defaultMeteor) {
|
137 | var checker = function(names) {
|
138 | fn(_.any(names, function(n) { return n === pkgName}))
|
139 | }
|
140 |
|
141 | if (!self.packageNames) {
|
142 |
|
143 | exec('meteor list', function(error, list) {
|
144 | var lines = list.split('\n');
|
145 |
|
146 | self.packageNames = _.map(lines, function(l) {
|
147 | return l.split(' ')[0]
|
148 | }).filter(function(n) { return n !== ''; });
|
149 |
|
150 | checker(self.packageNames);
|
151 | });
|
152 | } else {
|
153 | checker(self.packageNames);
|
154 | }
|
155 | } else {
|
156 | self.prepare(function() {
|
157 | fn(fs.existsSync(path.join(self.source.path, 'packages', pkgName)));
|
158 | });
|
159 | }
|
160 | }
|
161 |
|
162 | Meteor.prototype.toJson = function(lock) {
|
163 | if (this.defaultMeteor) {
|
164 | return {};
|
165 | } else {
|
166 | return this.source.toJson(lock);
|
167 | }
|
168 | };
|
169 |
|
170 | Meteor.prototype.equals = function(otherMeteor) {
|
171 | if (this.defaultMeteor)
|
172 | return otherMeteor.defaultMeteor;
|
173 |
|
174 | return !otherMeteor.defaultMeteor && this.source.equals(otherMeteor.source);
|
175 | };
|
176 |
|
177 | Meteor.installRoot = function() {
|
178 | return path.join(Meteorite.root(), 'meteors');
|
179 | };
|
180 |
|
181 | module.exports = Meteor;
|