mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
temporary solution to springboard in publish-for-arch
This commit is contained in:
@@ -217,6 +217,18 @@ _.extend(OfficialCatalog.prototype, {
|
||||
}
|
||||
},
|
||||
|
||||
// Find a release that uses the given version of a tool. See: publish-for-arch
|
||||
// in command-packages for more explanation. Returns information about a
|
||||
// particular release version, or null if such release version does not exist.
|
||||
getReleaseWithTool: function (toolSpec) {
|
||||
var self = this;
|
||||
buildmessage.assertInCapture();
|
||||
self._requireInitialized();
|
||||
return self._recordOrRefresh(function () {
|
||||
return _.findWhere(self.releaseVersions, { tool: toolSpec });
|
||||
});
|
||||
},
|
||||
|
||||
// Returns general (non-version-specific) information about a
|
||||
// release track, or null if there is no such release track.
|
||||
getReleaseTrack: function (name) {
|
||||
|
||||
@@ -376,6 +376,116 @@ main.registerCommand({
|
||||
if (buildmessage.jobHasMessages())
|
||||
return;
|
||||
|
||||
var versionLock = packageSource.dependencyVersions;
|
||||
//If we don't have a valid version lock file, that's weird! Maybe we are a
|
||||
//core package, which don't have version files. Anyway, we should not use
|
||||
//publish-for-arch in this case.
|
||||
if (!versionLock || !versionLock.toolVersion) {
|
||||
process.stderr.write(
|
||||
"This package has no valid version lock file: are you trying to use publish-for-arch on\n" +
|
||||
"a core package? Publish-for-arch cannot guarantee safety. Please use\n" +
|
||||
"publish --existing-version instead.\n");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Let's separate out the tool, if we can. If we can't, thats super bad, but
|
||||
// hopefully will not happen.
|
||||
var oldTool = versionLock.toolVersion.split('@');
|
||||
if (oldTool.length !== 2) {
|
||||
process.stderr.write(
|
||||
"The version lock file on this package specifies an invalid meteor tool. That's weird.\n" +
|
||||
"Publish-for-arch cannot guarantee safety with a corrupted version lock file! You can use\n" +
|
||||
"publish --existing-version to try to get around this?\n");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var toolPackage = oldTool[0];
|
||||
var toolVersion = oldTool[1];
|
||||
if (toolVersion === "CHECKOUT" &&
|
||||
!files.inCheckout()) {
|
||||
process.stderr.write(
|
||||
"This package was published from a checkout of meteor! The tool cannot replicate\n" +
|
||||
"that environment and will not even try. Please checkout meteor at the \n" +
|
||||
"corresponding git commit and try again.\n");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (toolVersion !== "CHECKOUT") {
|
||||
if (files.inCheckout()) {
|
||||
// The code running here, is probably not what you think it is. You
|
||||
// might think that you are running from checkout, but we are going to
|
||||
// springboard into a built release that is not running the code that
|
||||
// you just wrote. That's super confusing, so we are not going to do
|
||||
// that. If you ever find yourself doing this... well, you are running
|
||||
// from checkout, so you can figure it out.
|
||||
process.stderr.write(
|
||||
"This package was published from a built version of meteor," +
|
||||
"but you are running from checkout!\nConsider running from a " +
|
||||
"proper Meteor release, so we can springboard correctly.\n");
|
||||
// process.stderr.exit(1);
|
||||
var sufficientlyReasonableReleaseVersion =
|
||||
catalog.official.getReleaseWithTool(versionLock.toolVersion);
|
||||
throw new
|
||||
main.SpringboardToSpecificRelease(
|
||||
sufficientlyReasonableReleaseVersion,
|
||||
"Errors while trying to publish for arch");
|
||||
|
||||
}
|
||||
var currentToolPackage = release.current.getToolsPackage();
|
||||
var currentToolVersion = release.current.getToolsVersion();
|
||||
if (currentToolPackage !== toolPackage ||
|
||||
currentToolVersion !== toolVersion) {
|
||||
// XXX: OK. Here is the story.
|
||||
//
|
||||
// Meteor does not have a concept of not running from release. That is,
|
||||
// it runs from a release, or from checkout, not from a stand-alone
|
||||
// tool. We don't record the release that we publish with in
|
||||
// publish-for-arch, because that doesn't make sense. However, we can't
|
||||
// just springboard to a tool, because, for now, in 0.9.3, we really
|
||||
// want this to work on packages published pre-0.9.3. Just putting in
|
||||
// springboarding to tool code is not going to work, because older
|
||||
// versions of Meteor will just try to spingboard anyway.
|
||||
//
|
||||
// This is kind of a transitional hack. Going forward, there are several
|
||||
// ways to fix this -- we could introduct some sort of local records (so
|
||||
// we could create a temporary release record and run meteor from
|
||||
// there), or we can teach meteor to just run from a tool, instead of a
|
||||
// release. I like the latter better from a conceptual standpoint (why
|
||||
// should we run from a release only?) but it doesn't have a lot of use
|
||||
// cases. Alternatively, we can learn to simulate a release for older
|
||||
// versions, and not for newer versions, or something. This will be
|
||||
// worth thinking about when we have more information on how the system
|
||||
// is set up and used.
|
||||
//
|
||||
// Now, a proof of correctness -- this relies on several things:
|
||||
//
|
||||
// 1. We only use the tool in order to publish. Other release
|
||||
// information is irrelevant. (If that's ever false, we should write the
|
||||
// release instead of the tool and save us the trouble)
|
||||
//
|
||||
// 2. Springboarding to a specific release will run the tool from that
|
||||
// release, and not end up springboarding us to a different
|
||||
// release. Even if there are patches for this release (or whatever), we
|
||||
// are going to run the tool version of the release that we select here.
|
||||
//
|
||||
// 3. The only way to run a tool currently is from a release --
|
||||
// otherwise, we wouldn't need this explanation. (There is no way to
|
||||
// remove a release from existence.) Ergo, there must be a release that
|
||||
// contains a given tool, that we first used to publish this package.
|
||||
//
|
||||
// From 1 & 2, we get the idea that any release with the valid tool
|
||||
// version will do. From 3, we know that such a release exists.
|
||||
//
|
||||
// XXX Once again, this is a hack. Various things could happen to change
|
||||
// the above-mentioned points. When they do happen, in the not-so-near
|
||||
// future, we will have more information on how to actually solve this
|
||||
// problem.
|
||||
var sufficientlyReasonableReleaseVersion =
|
||||
catalog.official.getReleaseWithTool(versionLock.toolVersion);
|
||||
throw new
|
||||
main.SpringboardToSpecificRelease(sufficientlyReasonableReleaseVersion);
|
||||
}
|
||||
}
|
||||
|
||||
// Now compile it! Once again, everything should compile, and if
|
||||
// it doesn't we should fail. Hopefully, of course, we have
|
||||
|
||||
@@ -95,6 +95,13 @@ main.SpringboardToLatestRelease = function (track) {
|
||||
this.track = track;
|
||||
};
|
||||
|
||||
// Exception to throw from a command to exit, restart, and reinvoke
|
||||
// the command with the given Meteor release.
|
||||
main.SpringboardToSpecificRelease = function (releaseRecord, msg) {
|
||||
this.releaseRecord = releaseRecord;
|
||||
this.msg = msg;
|
||||
};
|
||||
|
||||
// Register a command-line command.
|
||||
//
|
||||
// options:
|
||||
@@ -270,7 +277,7 @@ var longHelp = exports.longHelp = function (commandName) {
|
||||
// not appear in the top-level help. If we one day want to make
|
||||
// these kinds of commands visible to casual users, we'll need a
|
||||
// way to mark them as visible or hidden.
|
||||
|
||||
|
||||
// Also, use helpDict to only include commands that have help text,
|
||||
// otherwise there is nothing to display
|
||||
if (n instanceof Command && ! n.hidden && helpDict[fullName])
|
||||
@@ -316,7 +323,7 @@ var longHelp = exports.longHelp = function (commandName) {
|
||||
// Exit and restart the program, with the same arguments, but using a
|
||||
// different version of the tool and/or forcing a particular release.
|
||||
//
|
||||
// - toolsVersion: required. the version of the tool to run. must
|
||||
// - release: required. the version of the tool to run. must
|
||||
// already be downloaded.
|
||||
// - releaseOverride: optional. if provided, a release name to force
|
||||
// us to use when restarting (this functions exactly like --release
|
||||
@@ -1226,6 +1233,7 @@ commandName + ": You're not in a Meteor project directory.\n" +
|
||||
} catch (e) {
|
||||
if (e === main.ShowUsage || e === main.WaitForExit ||
|
||||
e === main.SpringboardToLatestRelease ||
|
||||
e === main.SpringboardToSpecificReleaseg ||
|
||||
e === main.WaitForExit) {
|
||||
throw new Error(
|
||||
"you meant 'throw new main.Foo', not 'throw main.Foo'");
|
||||
@@ -1247,6 +1255,20 @@ commandName + ": You're not in a Meteor project directory.\n" +
|
||||
}
|
||||
springboard(latestRelease, latestRelease.name);
|
||||
// (does not return)
|
||||
} else if (e instanceof main.SpringboardToSpecificRelease) {
|
||||
// Springboard to a specific release.
|
||||
var nextRelease;
|
||||
var relName = e.releaseRecord.track + "@" + e.releaseRecord.version;
|
||||
var messages = buildmessage.capture(function () {
|
||||
nextRelease = release.load(relName);
|
||||
});
|
||||
if (messages.hasMessages()) {
|
||||
process.stderr.write("=> " + e.msg + ":\n\n");
|
||||
process.stderr.write(messages.formatMessages());
|
||||
process.exit(1);
|
||||
}
|
||||
springboard(nextRelease, relName);
|
||||
// (does not return)
|
||||
} else if (e instanceof main.WaitForExit) {
|
||||
return;
|
||||
} else if (e instanceof main.ExitWithCode) {
|
||||
|
||||
Reference in New Issue
Block a user