diff --git a/tools/catalog.js b/tools/catalog.js index 2c71d012e2..f15a7e9874 100644 --- a/tools/catalog.js +++ b/tools/catalog.js @@ -205,10 +205,12 @@ _.extend(Catalog.prototype, { }); } + var project = require("./project.js").project; // If we are called with 'ignore projectDeps', then we don't even look to // see what the project thinks is the reasonable version answer. We - // recalculate everything. - if (opts.ignoreProjectDeps) { + // recalculate everything. Also, if the project root path has not been + // initialized, we probably can't use the project's dependencies. + if (opts.ignoreProjectDeps || !project.rootDir) { return self.resolver.resolve(deps, constr, resolverOpts); } @@ -222,7 +224,6 @@ _.extend(Catalog.prototype, { // We do this, because when we record the local version lock files, we don't // want to record irrelevant dependencies (since we don't want those files // changing randomly). - var project = require("./project.js").project; var versions = project.getVersions(); resolverOpts.previousSolution = versions; var solution = self.resolver.resolve(deps, constr, resolverOpts); diff --git a/tools/project.js b/tools/project.js index 7e9a921b98..6c174aa20e 100644 --- a/tools/project.js +++ b/tools/project.js @@ -81,7 +81,8 @@ var Project = function () { // Packages & versions of all dependencies, including transitive dependencies, // program dependencies and so on, that this project uses. An object mapping a - // package name to its string version. Derived from self.combinedConstraints. + // package name to its string version. Derived from self.combinedConstraints + // and recorded in the .meteor/versions file. self.dependencies = null; // The package loader for this project, with the project's dependencies as its @@ -93,13 +94,11 @@ var Project = function () { // by any constraint-related operations. self.appId = null; - // True if the project has been initialized with a root directory and - // dependency information and false otherwise. - self.initialized = false; - - // Packages used by the sub-programs using of this project. Should not change - // without restart, we memoize this because we would otherwise need to reread - // it from disk every time we recalculate versions. + // Packages used by the sub-programs using of this project. Will not change + // while the app is running! Therefore, we can remember it, so we don't need + // to perform a bunch of reads when we recalculate combinedConstraints. + // + // XXX: Is this actually faster? self._programConstraints = null; // Whenever we change the constraints, we invalidate many constraint-related @@ -171,6 +170,17 @@ _.extend(Project.prototype, { self._depsUpToDate = false; }, + // Rereads all the on-disk files by reinitalizing the project with the same directory. + // + // We don't automatically reinitialize this singleton when an app is + // restarted, but an app restart is very likely caused by changes to our + // package configuration files. So, make sure to reload the constraints & + // dependencies here. + reload : function () { + var self = this; + self.setRootDir(self.rootDir); + }, + // Several fields in project are derived from constraints. Whenever we change // the constraints, we invalidate those fields, when we call on // dependency-related operations, we recompute them as needed. @@ -181,20 +191,22 @@ _.extend(Project.prototype, { _ensureDepsUpToDate : function () { var self = this; - // Aha, now we can initialize the project singleton. There is a dependency - // chain here -- to calculate project dependencies, we need to know what - // release we are on. So, we need to initialize it after the release. To - // figure out our release, we need to initialize the catalog. But we can't use - // the catalog's constraint solver until we initialize the release. - // - // Because this call is lazy, we don't need to worry about this, as long as we - // call things in the right order in main.js + // To calculate project dependencies, we need to know what release we are + // on, but to do that, we need to have a rootDirectory. So, we initialize + // the path first, and call 'ensureDepsUpToDate' lazily. if (!release.current) { throw new Error( "need to compute release before computing project dependencies."); } if (!self._depsUpToDate) { + + // XXX: I don't understand why we don't reread this automatically. + self.constraints = processPerConstraintLines( + getLines(self._constraintFile)); + self.dependencies = processPerConstraintLines( + getLines(self._versionsFile)); + // Use current release to calculate packages & combined constraints. var releasePackages = release.current.isProperRelease() ? release.current.getPackages() : {}; @@ -343,8 +355,6 @@ _.extend(Project.prototype, { return path.join(self.rootDir, '.meteor', 'packages'); }, - - // Give the contents of the project's .meteor/versions file to the caller. // // Returns an object mapping package name to its string version. diff --git a/tools/run-app.js b/tools/run-app.js index b758606098..3e51e9459e 100644 --- a/tools/run-app.js +++ b/tools/run-app.js @@ -389,6 +389,7 @@ _.extend(AppRunner.prototype, { _runOnce: function (onListen) { var self = this; + project.reload(); runLog.clearLog(); self.proxy.setMode("hold"); diff --git a/tools/tests/add-package.js b/tools/tests/add-package.js index 9658272431..673061280a 100644 --- a/tools/tests/add-package.js +++ b/tools/tests/add-package.js @@ -108,7 +108,6 @@ selftest.define("change packages", function () { run.waitSecs(5); run.match("running at"); run.match("localhost"); - // Add the local package 'say-something'. It should print a message. s.write(".meteor/packages", "standard-app-packages \n say-something"); run.waitSecs(2); @@ -144,7 +143,6 @@ selftest.define("change packages", function () { run.waitSecs(2); run.match("restarted"); - }); @@ -161,6 +159,7 @@ selftest.define("add packages", function () { console.log("XXX: this assumes that we are running from checkout"); run = s.run("add", "accounts-base", "--offline-catalog"); + run.match("Successfully added"); checkPackages(s, ["accounts-base", "standard-app-packages"]); @@ -168,7 +167,9 @@ selftest.define("add packages", function () { run = s.run("--once"); run = s.run("add", "say-something@1.0.0", "--offline-catalog"); + run.match("Successfully added"); + checkPackages(s, ["accounts-base", "say-something@1.0.0", "standard-app-packages"]); @@ -184,16 +185,15 @@ selftest.define("add packages", function () { "contains-plugin@1.1.0+local"]); run = s.run("remove", "say-something", "--offline-catalog"); - run.match("Removed say-something"); + run.match("Removed constraint say-something"); checkVersions(s, ["accounts-base", "depends-on-plugin", "standard-app-packages", "contains-plugin"]); - run = s.run("remove", "depends-on-plugin", "--offline-catalog"); run.match("removed dependency on contains-plugin"); - run.match("Removed depends-on-plugin"); + run.match("Removed constraint depends-on-plugin"); checkVersions(s, ["accounts-base",