Permalink
Browse files

[gh238] [bz5667423] application.json files in NPM packages can contri…

…bute as well
  • Loading branch information...
1 parent 1fd2775 commit d1390d7f619c79a7bcdc66b6327ce27b7dee019c @drewfish drewfish committed Jan 10, 2013
View
@@ -4,6 +4,7 @@
*.bak
*~
node_modules
+!tests/fixtures/app-jsons/node_modules
!tests/fixtures/packages/node_modules
!tests/fixtures/packages/node_modules/*/node_modules
arrowreport
@@ -165,6 +165,48 @@ YUI.add('addon-rs-config', function(Y, NAME) {
/**
+ * Creates a YCB configuration bundle using contents from multiple files.
+ * The appropriate dimensions.json file will be mixed in, and doesn't need
+ * to be part of the list of files.
+ * @method createMultipartYCB
+ * @param {array} paths list of files to load
+ * @return {YCB|undefined} return a YCB library object, or undefined if an error occurs
+ */
+ createMultipartYCB: function(paths) {
+ var p,
+ path,
+ config,
+ s,
+ section,
+ settings = {},
+ bundle = [];
+ bundle.push(this.getDimensions()[0]);
+ for (p = 0; p < paths.length; p += 1) {
+ path = paths[p];
+ config = this.readConfigSync(path);
+ if (!Y.Lang.isArray(config)) {
+ Y.log('not a YCB file: ' + path, 'error', NAME);
+ return;
+ }
+ for (s = 0; s < config.length; s += 1) {
+ section = config[s];
+ if (!Y.Lang.isArray(section.settings)) {
+ Y.log('missing "settings" in YCB file: ' + path, 'error', NAME);
+ return;
+ }
+ if (settings[section.settings]) {
+ Y.log('settings "' + section.settings + '" exists in both \n' + path + ' and\n' + settings[section.settings], 'error', NAME);
+ return;
+ }
+ settings[section.settings] = path;
+ bundle.push(section);
+ }
+ }
+ return new libycb.Ycb(bundle);
+ },
+
+
+ /**
* Using AOP, this is called after the ResourceStore's version.
* @method findResourceVersionByConvention
* @param {object} source metadata about where the resource is located
@@ -199,6 +241,10 @@ YUI.add('addon-rs-config', function(Y, NAME) {
if (mojitType && 'shared' !== mojitType) {
use = true;
}
+ // use application.{json,yaml,yml} in bundles as well
+ if ('bundle' === fs.rootType && 'application' === fs.basename) {
+ use = true;
+ }
if (!use) {
return;
}
@@ -237,7 +283,7 @@ YUI.add('addon-rs-config', function(Y, NAME) {
affinity: 'common',
selector: '*'
};
- if ('app' !== source.fs.rootType) {
+ if ('mojit' === source.fs.rootType) {
res.mojit = mojitType;
}
res.name = libpath.join(source.fs.subDir, baseParts.join('.'));
@@ -36,16 +36,10 @@ YUI.add('addon-rs-selector', function(Y, NAME) {
* @return {nothing}
*/
initializer: function(config) {
- var dims,
- json;
this.appRoot = config.appRoot;
this.mojitoRoot = config.mojitoRoot;
- dims = config.host.config.getDimensions();
- json = config.host.config.readConfigSimple(libpath.join(this.appRoot, 'application.json'));
- json = dims.concat(json);
- // TODO: use rs.config for this too
- this._appConfigYCB = new libycb.Ycb(json);
+ this._appConfigYCB = config.host.getAppConfigYCB();
this._poslCache = {}; // context: POSL
},
@@ -223,7 +223,15 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
this._validDims = this._parseValidDims(this.config.getDimensions());
this.validateContext(this._config.context);
this._fwConfig = this.config.readConfigSimple(this._libs.path.join(this._config.mojitoRoot, 'config.json'));
+
+ // We use this during preload() before we even know about all the
+ // application.jsons. This might be OK, since we'll have the real
+ // values during the second pass.
+ // In practice, this only applies to "mojitDirs" and "mojitsDirs",
+ // which can only be given in the app-level application.json.
this._appConfigStatic = this.getAppConfig({});
+
+ this._appConfigYCB = null; // libycb object
},
destructor: function() {},
@@ -349,13 +357,20 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
key,
ycb;
+ ctx = this.blendStaticContext(ctx);
key = JSON.stringify(ctx || {});
if (this._appConfigCache[key]) {
return JSON.parse(this._appConfigCache[key]);
}
- ycb = this.config.readConfigYCB(this._libs.path.join(this._config.root, 'application.json'), ctx);
+ if (this._appConfigYCB) {
+ ycb = this._appConfigYCB.read(ctx);
+ } else {
+ // This is generally only used to populate the initial this._appConfigStatic.
+ // After preload() we'll have this._appConfigYCB.
+ ycb = this.config.readConfigYCB(this._libs.path.join(this._config.root, 'application.json'), ctx);
+ }
appConfig = Y.mojito.util.blend(this._fwConfig.appConfigBase, this._config.appConfig);
appConfig = Y.mojito.util.blend(appConfig, ycb);
@@ -364,6 +379,19 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
return appConfig;
},
+
+
+ /**
+ * Returns the YCB library object for the application config.
+ * This is rarely what you want to use. getAppConfig() is a better choice.
+ * @method getAppConfigYCB
+ * @return {YCB} YCB library object for the application config
+ */
+ getAppConfigYCB: function() {
+ return this._appConfigYCB;
+ },
+
+
/**
* Preloads everything in the app, and as well pertinent parts of
* the framework.
@@ -374,10 +402,19 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
preload: function() {
// We need to do an initial sweep to find the resource store addons.
this.preloadResourceVersions();
+
+ // Now that we've found all the application.jsons, we can aggregate them.
+ this._initAppConfig();
+
+ // We need to rebuild _appConfigStatic -before- we load the addons,
+ // since they might (they do) cache the results of getStaticAppConfig().
+ this._appConfigStatic = this.getAppConfig({});
+
// And then use them.
this.loadAddons();
// Then, do another sweep so that the loaded addons can be used.
this.preloadResourceVersions();
+
this.makeResourceVersions();
this.resolveResourceVersions();
},
@@ -2081,6 +2118,36 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
});
Y.use.apply(Y, Object.keys(modules));
Y.applyConfig({ useSync: false });
+ },
+
+
+ /**
+ * Initializes the special multi-file YCB library for all the application.jsons.
+ * The object is used by getAppConfig().
+ * @private
+ * @method _initAppConfig
+ * @return {nothing}
+ */
+ _initAppConfig: function() {
+ var r,
+ res,
+ ress,
+ paths = [];
+
+ // TODO: detect conflicting peers (i.e. both application.json and application.yaml)
+
+ ress = this.getResourceVersions({type: 'config', name: 'application'});
+ for (r = 0; r < ress.length; r += 1) {
+ res = ress[r];
+ paths.push(res.source.fs.fullPath);
+ }
+ this._appConfigYCB = this.config.createMultipartYCB(paths);
+ if (!this._appConfigYCB) {
+ throw new Error("failed to create a YCB config from the following files:\n " + paths.join("\n "));
+ }
+ // New way to load means invalidating the whole cache.
+ // In practice, the cache likely only has the static version.
+ this._appConfigCache = {};
}
@@ -0,0 +1,7 @@
+[
+ {
+ "testKey1": "testVal1",
+ "testKey2": "testVal2",
+ "testKey3": "testVal3"
+ }
+]
@@ -0,0 +1,8 @@
+{
+ "foo": {
+ "settings": [ "master" ],
+ "testKey1": "testVal1",
+ "testKey2": "testVal2",
+ "testKey3": "testVal3"
+ }
+}
@@ -0,0 +1,8 @@
+[
+ {
+ "settings": [ "master" ],
+ "testKey1": "testVal1",
+ "testKey2": "testVal2",
+ "testKey3": "testVal3"
+ }
+]
@@ -0,0 +1,8 @@
+[
+ {
+ "settings": [ "master" ],
+ "testKey1": "testVal1-app2",
+ "testKey2": "testVal2-app2",
+ "testKey3": "testVal3-app2"
+ }
+]
@@ -0,0 +1,14 @@
+[
+ {
+ "settings": [ "device:iphone" ],
+ "selector": "iphone"
+ },
+ {
+ "settings": [ "device:android" ],
+ "selector": "droid"
+ },
+ {
+ "settings": [ "device:android", "environment:dev" ],
+ "selector": "devdroid"
+ }
+]
@@ -0,0 +1,18 @@
+{
+ "name": "devices",
+ "version": "666.0.0",
+ "description": "devices package",
+ "author": "Team Mojito (http://developer.yahoo.com/cocktails/mojito)",
+ "dependencies": {},
+ "main": ".",
+ "engines": {
+ "node": ">= 0.4.0",
+ "npm": ">= 1.0.0"
+ },
+ "devDependencies": {},
+ "yahoo": {
+ "mojito": {
+ "type": "bundle"
+ }
+ }
+}
@@ -0,0 +1,14 @@
+[
+ {
+ "settings": [ "runtime:server" ],
+ "selector": "shelves",
+ "testKey1": "testVal1-server",
+ "pathos": "portended"
+ },
+ {
+ "settings": [ "runtime:client" ],
+ "selector": "right",
+ "testKey2": "testVal2-client",
+ "testKey4": "testVal4-client"
+ }
+]
@@ -0,0 +1,18 @@
+{
+ "name": "runtimes",
+ "version": "666.0.0",
+ "description": "runtimes package",
+ "author": "Team Mojito (http://developer.yahoo.com/cocktails/mojito)",
+ "dependencies": {},
+ "main": ".",
+ "engines": {
+ "node": ">= 0.4.0",
+ "npm": ">= 1.0.0"
+ },
+ "devDependencies": {},
+ "yahoo": {
+ "mojito": {
+ "type": "bundle"
+ }
+ }
+}
@@ -0,0 +1,13 @@
+{
+ "name": "root",
+ "version": "666.0.0",
+ "description": "root package",
+ "author": "Team Mojito (http://developer.yahoo.com/cocktails/mojito)",
+ "dependencies": {},
+ "main": ".",
+ "engines": {
+ "node": ">= 0.4.0",
+ "npm": ">= 1.0.0"
+ },
+ "devDependencies": {}
+}
Oops, something went wrong. Retry.

0 comments on commit d1390d7

Please sign in to comment.