forked from meteor/meteor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
upgraders.js
277 lines (245 loc) · 10.3 KB
/
upgraders.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
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/* eslint no-console: 0 */
var _ = require('underscore');
var files = require('./fs/files.js');
var Console = require('./console/console.js').Console;
import main from './cli/main.js';
import buildmessage from './utils/buildmessage.js';
import * as cordova from './cordova';
// This file implements "upgraders" --- functions which upgrade a Meteor app to
// a new version. Each upgrader has a name (registered in upgradersByName).
//
// You can test upgraders by running "meteor admin run-upgrader myupgradername".
//
// Upgraders are run automatically by "meteor update". It looks at the
// .meteor/.finished-upgraders file in the app and runs every upgrader listed
// here that is not in that file; then it appends their names to that file.
// Upgraders are run in the order they are listed in upgradersByName below.
//
// Upgraders receive a projectContext that has been fully prepared for build.
var printedNoticeHeaderThisProcess = false;
var maybePrintNoticeHeader = function () {
if (printedNoticeHeaderThisProcess)
return;
Console.info();
Console.info("-- Notice --");
Console.info();
printedNoticeHeaderThisProcess = true;
};
// How to do package-specific notices:
// (a) A notice that occurs if a package is used indirectly or directly.
// if (projectContext.packageMap.getInfo('accounts-ui')) {
// console.log(
// "\n" +
// " Accounts UI has totally changed, yo.");
// }
//
// (b) A notice that occurs if a package is used directly.
// if (projectContext.projectConstraintsFile.getConstraint('accounts-ui')) {
// console.log(
// "\n" +
// " Accounts UI has totally changed, yo.");
// }
var upgradersByName = {
"notices-for-0.9.0": function (projectContext) {
maybePrintNoticeHeader();
var smartJsonPath =
files.pathJoin(projectContext.projectDir, 'smart.json');
if (files.exists(smartJsonPath)) {
// Meteorite apps:
console.log(
"0.9.0: Welcome to the new Meteor package system! You can now add any Meteor\n" +
" package to your app (from more than 1800 packages available on the\n" +
" Meteor Package Server) just by typing 'meteor add <packagename>', no\n" +
" Meteorite required.\n" +
"\n" +
" It looks like you have been using Meteorite with this project. To\n" +
" migrate your project automatically to the new system:\n" +
" (1) upgrade your Meteorite with 'npm install -g meteorite', then\n" +
" (2) run 'mrt migrate-app' inside the project.\n" +
" Having done this, you no longer need 'mrt' and can just use 'meteor'.\n");
} else {
// Non-Meteorite apps:
console.log(
"0.9.0: Welcome to the new Meteor package system! You can now add any Meteor\n" +
" package to your app (from more than 1800 packages available on the\n" +
" Meteor Package Server) just by typing 'meteor add <packagename>'. Check\n" +
" out the available packages by typing 'meteor search <term>' or by\n" +
" visiting atmospherejs.com.\n");
}
console.log();
},
"notices-for-0.9.1": function () {
maybePrintNoticeHeader();
console.log(
"0.9.1: Meteor 0.9.1 includes changes to the Blaze API, in preparation for 1.0.\n" +
" Many previously undocumented APIs are now public and documented. Most\n" +
" changes are backwards compatible, except that templates can no longer\n" +
" be named \"body\" or \"instance\".\n");
console.log();
},
// In 0.9.4, the platforms file contains "server" and "browser" as platforms,
// and before it only had "ios" and/or "android". We auto-fix that in
// PlatformList anyway, but we also need to pull platforms from the old
// cordova-platforms filename.
"0.9.4-platform-file": function (projectContext) {
var oldPlatformsPath =
files.pathJoin(projectContext.projectDir, ".meteor", "cordova-platforms");
try {
var oldPlatformsFile = files.readFile(oldPlatformsPath);
} catch (e) {
// If the file doesn't exist, there's no transition to do.
if (e && e.code === 'ENOENT')
return;
throw e;
}
var oldPlatforms = _.compact(_.map(
files.splitBufferToLines(oldPlatformsFile), files.trimSpaceAndComments));
// This method will automatically add "server" and "browser" and sort, etc.
projectContext.platformList.write(oldPlatforms);
files.unlink(oldPlatformsPath);
},
"notices-for-facebook-graph-api-2": function (projectContext) {
// Note: this will print if the app has facebook as a dependency, whether
// direct or indirect. (This is good, since most apps will be pulling it in
// indirectly via accounts-facebook.)
if (projectContext.packageMap.getInfo('facebook')) {
maybePrintNoticeHeader();
Console.info(
"This version of Meteor now uses version 2.2 of the Facebook API",
"for authentication, instead of 1.0. If you use additional Facebook",
"API methods beyond login, you may need to request new",
"permissions.\n\n",
"Facebook will automatically switch all apps to API",
"version 2.0 on April 30th, 2015. Please make sure to update your",
"application's permissions and API calls by that date.\n\n",
"For more details, see",
"https://github.com/meteor/meteor/wiki/Facebook-Graph-API-Upgrade",
Console.options({ bulletPoint: "1.0.5: " })
);
}
},
"1.2.0-standard-minifiers-package": function (projectContext) {
// Minifiers are extracted into a new package called "standard-minifiers"
projectContext.projectConstraintsFile.addPackages(
['standard-minifiers']);
projectContext.projectConstraintsFile.writeIfModified();
},
"1.2.0-meteor-platform-split": function (projectContext) {
const packagesFile = projectContext.projectConstraintsFile;
// meteor-platform is split into a series of smaller umbrella packages
// Only run this upgrader if the app has meteor-platform
if (packagesFile.getConstraint('meteor-platform')) {
packagesFile.removePackages(['meteor-platform']);
packagesFile.addPackages([
// These packages replace meteor-platform in newly created apps
'meteor-base',
'mobile-experience',
'mongo',
'blaze-html-templates',
'session',
'jquery',
'tracker',
// These packages are not in newly created apps, but were in
// meteor-platform so we need to add them just in case
'logging',
'reload',
'random',
'ejson',
'spacebars',
'check',
]);
packagesFile.writeIfModified();
}
},
"1.2.0-cordova-changes": function (projectContext) {
// Remove Cordova project directory to start afresh
// and avoid a broken project
files.rm_recursive(projectContext.getProjectLocalDirectory(
'cordova-build'));
// Cordova plugin IDs have changed as part of moving to npm, so we convert
// old plugin IDs to new IDs. We also convert old-style GitHub tarball URLs
// to new Git URLs, and check if other Git URLs contain a SHA reference.
const pluginsFile = projectContext.cordovaPluginsFile;
let messages;
if (files.exists(pluginsFile.filename)) {
messages = buildmessage.capture(
{ title: `converting Cordova plugins` }, () => {
let pluginVersions = pluginsFile.getPluginVersions();
pluginVersions = cordova.convertPluginVersions(pluginVersions);
pluginsFile.write(pluginVersions);
});
}
// Don't display notice if the project has no Cordova platforms added
if (_.isEmpty(projectContext.platformList.getCordovaPlatforms())) return;
maybePrintNoticeHeader();
// Print error messages generated during plugin conversion, if any
if (messages && messages.hasMessages()) {
Console.printMessages(messages);
}
},
"1.2.0-breaking-changes": function () {
maybePrintNoticeHeader();
Console.info(
`Meteor 1.2 includes many changes and improvements to the build system, \
some of which might require small changes to apps and packages. Please read \
the guide about breaking changes here:`,
Console.url("https://github.com/meteor/meteor/wiki/Breaking-changes-in-Meteor-1.2"),
Console.options({ bulletPoint: "1.2: " })
);
},
"1.3.0-split-minifiers-package": function (projectContext) {
const packagesFile = projectContext.projectConstraintsFile;
// Minifiers are extracted into a new package called "standard-minifiers"
if (packagesFile.getConstraint('standard-minifiers')) {
packagesFile.removePackages(['standard-minifiers']);
packagesFile.addPackages([
// These packages replace meteor-platform in newly created apps
'standard-minifier-css',
'standard-minifier-js',
]);
}
packagesFile.writeIfModified();
},
"1.4.0-remove-old-dev-bundle-link": function (projectContext) {
const oldDevBundleLink =
files.pathJoin(projectContext.projectDir, ".meteor", "dev_bundle");
files.rm_recursive(oldDevBundleLink);
},
"1.4.1-add-shell-server-package": function (projectContext) {
const packagesFile = projectContext.projectConstraintsFile;
packagesFile.addPackages(["shell-server"]);
packagesFile.writeIfModified();
},
////////////
// PLEASE. When adding new upgraders that print mesasges, follow the
// examples for 0.9.0 and 0.9.1 above. Specifically, formatting
// should be:
//
// 1.x.y: Lorem ipsum messages go here...
// ...and linewrapped on the right column
//
// (Or just use Console.info with bulletPoint)
////////////
};
exports.runUpgrader = function (projectContext, upgraderName) {
// This should only be called from the hidden run-upgrader command or by
// "meteor update" with an upgrader from one of our releases, so it's OK if
// error handling is just an exception.
if (! _.has(upgradersByName, upgraderName))
throw new Error("Unknown upgrader: " + upgraderName);
upgradersByName[upgraderName](projectContext);
};
exports.upgradersToRun = function (projectContext) {
var ret = [];
var finishedUpgraders = projectContext.finishedUpgraders.readUpgraders();
// This relies on the fact that Node guarantees object iteration ordering.
_.each(upgradersByName, function (func, name) {
if (! _.contains(finishedUpgraders, name)) {
ret.push(name);
}
});
return ret;
};
exports.allUpgraders = function () {
return _.keys(upgradersByName);
};