forked from meteor/meteor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrelease.js
263 lines (223 loc) · 8.25 KB
/
release.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
var _ = require('underscore');
var files = require('./files.js');
var warehouse = require('./warehouse.js');
var catalog = require('./catalog.js');
var utils = require('./utils.js');
var buildmessage = require('./buildmessage.js');
var release = exports;
var Release = function (options) {
var self = this;
// If an actual, proper, "released" release, the name of the
// release, eg, "[email protected]". If not a proper release, null.
self.name = options.name;
if (self.name === null) {
// Running from checkout.
self._manifest = null;
} else {
// Running a proper release
self._manifest = options.manifest;
}
};
_.extend(Release.prototype, {
// True if an actual, proper, "released" release. If so, this.name
// will have the name of the release, eg, "1.0".
isProperRelease: function () {
return this.name !== null;
},
// True if this "release" is actually a checkout on disk. It is
// defined by the packages in the checkout rather than by a
// manifest. this.name will be null.
isCheckout: function () {
return this.name === null;
},
getReleaseTrack: function () {
var self = this;
if (! self.isProperRelease())
throw new Error("not a proper release?");
return self.name.split('@')[0];
},
getReleaseVersion: function () {
var self = this;
if (! self.isProperRelease())
throw new Error("not a proper release?");
return self.name.split('@')[1];
},
// Return the package name for the command-line tools that this release
// uses. Valid only for proper releases.
getToolsPackage: function () {
var self = this;
if (! self.isProperRelease())
throw new Error("not a proper release?");
// XXX validate
return self._manifest.tool.split('@')[0];
},
// Return the version of the command-line tools that this release
// uses. Valid only for proper releases.
getToolsVersion: function () {
var self = this;
if (! self.isProperRelease())
throw new Error("not a proper release?");
// XXX validate
return self._manifest.tool.split('@')[1];
},
// Return the package name and version of the command-line tools that this
// release uses. Valid only for proper releases.
getToolsPackageAtVersion: function () {
var self = this;
if (! self.isProperRelease())
throw new Error("not a proper release?");
return self._manifest.tool;
},
// Return the tool that we are using. If this is a proper release, return the
// tool package listed in the manifest, otherwise return the version of the
// meteor-tool package in checkout.
getCurrentToolsVersion: function () {
var self = this;
if (release.current.name) {
return self._manifest.tool;
} else {
return "meteor-tool@CHECKOUT";
}
},
// Return a list of the upgraders (project migrations) for this
// release, an (ordered!) array of strings. Valid only for proper
// releases.
getUpgraders: function () {
var self = this;
if (! self.isProperRelease())
throw new Error("not a proper release?");
return self._manifest.upgraders || [];
},
getPackages: function () {
var self = this;
if (! self.isProperRelease())
throw new Error("not a proper release?");
return self._manifest.packages;
},
getCatalogReleaseData: function () {
var self = this;
if (! self.isProperRelease())
throw new Error("not a proper release?");
return self._manifest;
},
getDisplayName: function (options) {
var self = this;
return utils.displayRelease(self.getReleaseTrack(),
self.getReleaseVersion(),
options);
}
});
// The current release. Once set, this does not change for the
// lifetime of the process.
//
// It is possible that we don't have a release. Currently this only
// comes up in one case: an app was created with a checkout version of
// Meteor, and then run with a release version of Meteor. In this case
// release.current will be null. (It will also be null during startup,
// until setRelease has been called.)
//
// (If you want to change the current release, you have to
// springboard, the same as if you want to change the current tools
// version. Besides being simpler to reason about, this helps to
// prepare us for a future where the 'meteor' tool itself is a Meteor
// app, running against a particular Meteor release.)
release.current = null;
// True if we are using release.current because we were forced to do that by the
// '--release' command line option or via throwing SpringboardToLatestRelease,
// else false. (It is true anytime --release was passed, even if it's the same
// release we would have used anyway. It is false anytime the current release is
// a checkin.) null if release.current is null.
release.forced = null;
// True if the release was explicitly specified by the user with the --release
// flag. Unlike release.forced, this is false when the release is overridden via
// SpringboardToLatestRelease.
release.explicit = null;
// True if release.current is the release we'd use if we wanted to run the app
// in the current project. (taking into account release.forced and whether we're
// currently running from a checkout).
release.usingRightReleaseForApp = function (projectContext) {
if (release.current === null)
throw new Error("no release?");
if (! files.usesWarehouse() || release.forced)
return true;
return release.current.name === projectContext.releaseFile.fullReleaseName;
};
// Return the name of the latest release that is downloaded and ready
// for use. May not be called when running from a checkout.
// 'track' is optional (it defaults to the default track).
release.latestKnown = function (track) {
if (! files.usesWarehouse())
throw new Error("called from checkout?");
// For self-test only.
if (process.env.METEOR_TEST_LATEST_RELEASE)
return process.env.METEOR_TEST_LATEST_RELEASE;
var defaultRelease = catalog.official.getDefaultReleaseVersion(track);
if (!defaultRelease) {
return null;
}
return defaultRelease.track + '@' + defaultRelease.version;
};
// Load a release and return it as a Release object without setting
// release.current to that release. Unlike release.setCurrent(), this
// may be called as many times as you like.
//
// This will fetch the release from the server if it isn't cached
// locally. If that happens it will print progress messages.
//
// Arguments:
// - name: release name to use. Or pass 'null' to use a checkout
// - options:
// - quiet: if the release has to be downloaded, don't print
// progress messages.
//
// Throws:
// - files.OfflineError if it was not possible to load the
// release because it's not locally cached and we're not online.
// - warehouse.NoSuchReleaseError if no release called 'name' exists
// in the world (confirmed with server).
release.load = function (name, options) {
options = options || {};
if (! name) {
return new Release({ name: null });
}
var parts = name.split('@');
if (parts.length > 2) {
// XXX #Pre090 better error handling
throw Error("too many @s in release name");
}
var track, version;
if (parts.length == 2) {
track = parts[0];
version = parts[1];
} else {
track = catalog.DEFAULT_TRACK;
version = parts[0];
name = track + '@' + version;
}
var releaseVersion = catalog.official.getReleaseVersion(track, version);
if (releaseVersion === null) {
throw new release.NoSuchReleaseError;
}
return new Release({
name: name,
manifest: releaseVersion // XXX rename from manifest?
});
};
// Called by the startup code to set release.current. May only be
// called once.
//
// - releaseObject: a Release as returned from release.load()
// - forced: true if the chosen release was forced from the command
// line (by the user or by the update springboard).
// - explicit: true if the release was specifically requested by the user.
release.setCurrent = function (releaseObject, forced, explicit) {
if (release.current)
throw new Error("release set twice?");
release.current = releaseObject;
release.forced = !! forced;
release.explicit = !! explicit;
};
// An exception meaning that you asked for a release that doesn't exist in the
// new packaging world. (It may still exist in the pre-0.9.0 packaging world.)
release.NoSuchReleaseError = function () {
};