Skip to content
This repository has been archived by the owner on Oct 30, 2018. It is now read-only.

Commit

Permalink
fix bug 4404935, including work from pr580 and pr670
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichun Zhan committed Nov 8, 2012
1 parent 14e96cc commit df6149b
Show file tree
Hide file tree
Showing 38 changed files with 517 additions and 64 deletions.
25 changes: 19 additions & 6 deletions docs/dev_guide/intro/mojito_configuring.rst
@@ -1,5 +1,3 @@


==================
Configuring Mojito
==================
Expand All @@ -13,10 +11,13 @@ configured differently, but uses same general file format consisting of JSON.
File Format
-----------

All configuration files in Mojito have a general top-level structure and are in JSON format.
At the top level of each configuration file is an array. Each item of the array is an
object that configures one component of Mojito, such as logging, assets, mojits, static
resources, etc.
JSON
####

By default, configuration files in Mojito have a general top-level structure and are
in JSON format. At the top level of each configuration file is an array. Each item of
the array is an object that configures one component of Mojito, such as logging, assets,
mojits, static resources, etc.

Each configuration object is required to have a ``settings`` property that specifies
conditions for applying the configuration settings. These conditions could be used to
Expand All @@ -38,6 +39,17 @@ Below is the skeleton of a configuration file. See `Application Configuration`_
...
]
YAML
####

Mojito also supports configuration files in YAML format. The YAML file extension could
be ``.yaml`` or ``.yml``. Mojito allows comments in the YAML files. When both JSON file
and YAML files are present, the YAML file is used and a warning is issued. For the data
types of the YAML elements, please see the JSON configuration tables in
:ref:`Application Configuration <configure_mj-app>`, :ref:`Routing <configure_mj-routing>`,
and :ref:`Mojit Configuration <configure_mj-mojit>`.

.. _configure_mj-app:

Application Configuration
Expand Down Expand Up @@ -818,6 +830,7 @@ function in the controller of the ``Foo`` mojit.
}
]
.. _configure_mj-routing:

Routing
=======
Expand Down
Expand Up @@ -29,7 +29,7 @@ YUI.add('flickrModel', function (Y, NAME) {
// Execute against YQL
Y.YQL(select, function(rawYql) {
// Handle empty response.
if (null === rawYql || 0 === rawYql.query.count) {
if (null === rawYql || !rawYql.query.count || !rawYql.query.results) {
callback([]);
}
// Process data.
Expand Down
80 changes: 57 additions & 23 deletions lib/app/addons/rs/config.server.js
Expand Up @@ -25,7 +25,8 @@ YUI.add('addon-rs-config', function(Y, NAME) {
var libfs = require('fs'),
libpath = require('path'),
existsSync = libfs.existsSync || libpath.existsSync,
libycb = require('ycb');
libycb = require('ycb'),
libyaml = require('js-yaml');

function RSAddonConfig() {
RSAddonConfig.superclass.constructor.apply(this, arguments);
Expand Down Expand Up @@ -61,33 +62,66 @@ YUI.add('addon-rs-config', function(Y, NAME) {
return Y.mojito.util.copy(this._ycbDims);
},


/**
* Reads and parses a JSON file.
* @method readConfigJSON
* @param {string} fullPath path to JSON file
* @return {user-defined} contents of JSON file
* Same as readConfigSync except the result is cached for future calls.
* @method readConfigSimple
* @param {string} fullPath path to JSON or YAML file
* @return {user-defined} contents of file as an object
*/
// TODO: async interface
readConfigJSON: function(fullPath) {
var json,
contents;
if (!existsSync(fullPath)) {
return {};
}
readConfigSimple: function(fullPath) {
var json;
json = this._jsonCache[fullPath];
if (!json) {
try {
contents = libfs.readFileSync(fullPath, 'utf-8');
json = Y.JSON.parse(contents);
} catch (e) {
throw new Error('Error parsing JSON file: ' + fullPath);
}
json = this.readConfigSync(fullPath);
this._jsonCache[fullPath] = json;
}

return Y.mojito.util.copy(json);
},

/**
* Reads and parses a JSON or YAML structured file.
* @method readConfigSync
* @param {string} fullPath path to JSON or YAML file
* @return {user-defined} contents of file as an object
*/
readConfigSync: function (filePath) {

var extensions = ['.yml', '.yaml', '.json'],
i,
json = false,
raw,
obj = {};

if (libpath.extname(filePath)) {
filePath = filePath.slice(0, libpath.extname(filePath).length * -1);
}

for (i = extensions.length - 1; i >= 0; i -= 1) {
try {
raw = libfs.readFileSync(filePath + extensions[i], 'utf8');
try {
if (i === 2) { // json
obj = JSON.parse(raw);
json = true;
} else { // yaml or yml
obj = libyaml.load(raw);
if (json) {
Y.log(filePath + extensions[2] + ' exists. But ' + extensions[i] + ' file will be used', 'warn', NAME);
}
}
} catch (parseErr) {
throw new Error(parseErr);
}
} catch (err) {
if (err.errno !== 34) { // if the error was not "no such file or directory" report it
throw new Error("Error parsing file: " + filePath + extensions[i] + "\n" + err);
}
}
}
return obj;
},


/**
* Reads a configuration file that is in YCB format.
Expand All @@ -114,7 +148,7 @@ YUI.add('addon-rs-config', function(Y, NAME) {
cacheKey = Y.JSON.stringify(ctx);
ycb = this._ycbCache[fullPath][cacheKey];
if (!ycb) {
json = this.readConfigJSON(fullPath);
json = this.readConfigSimple(fullPath);
json = this._ycbDims.concat(json);
ycb = libycb.read(json, ctx);
this._ycbCache[fullPath][cacheKey] = ycb;
Expand Down Expand Up @@ -142,8 +176,8 @@ YUI.add('addon-rs-config', function(Y, NAME) {
if ('.' !== fs.subDir) {
return;
}
// we only care about json files
if ('.json' !== fs.ext) {
// we only care about json or yaml files
if ('.json' !== fs.ext && '.yaml' !== fs.ext && '.yml' !== fs.ext) {
return;
}
// use package.json for the app and the mojit
Expand Down Expand Up @@ -217,7 +251,7 @@ YUI.add('addon-rs-config', function(Y, NAME) {
if (!existsSync(path)) {
path = libpath.join(this.mojitoRoot, 'dimensions.json');
}
return this.readConfigJSON(path);
return this.readConfigSimple(path);
}


Expand Down
4 changes: 2 additions & 2 deletions lib/app/addons/rs/selector.server.js
Expand Up @@ -4,7 +4,7 @@
* See the accompanying LICENSE file for terms.
*/

/*jslint anon:true, sloppy:true, nomen:true*/
/*jslint anon:true, sloppy:true, nomen:true, stupid:true*/
/*global YUI*/


Expand Down Expand Up @@ -42,7 +42,7 @@ YUI.add('addon-rs-selector', function(Y, NAME) {
this.mojitoRoot = config.mojitoRoot;

dims = config.host.config.getDimensions();
json = config.host.config.readConfigJSON(libpath.join(this.appRoot, 'application.json'));
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);
Expand Down
2 changes: 1 addition & 1 deletion lib/app/addons/rs/url.server.js
Expand Up @@ -113,7 +113,7 @@ YUI.add('addon-rs-url', function(Y, NAME) {
mojitIsPublic = false;
if (mojitRes) {
packageJson = libpath.join(mojitRes.source.fs.fullPath, 'package.json');
packageJson = store.config.readConfigJSON(packageJson);
packageJson = store.config.readConfigSimple(packageJson);
if ('public' === (packageJson.yahoo &&
packageJson.yahoo.mojito &&
packageJson.yahoo.mojito['package'])) {
Expand Down
33 changes: 25 additions & 8 deletions lib/app/commands/start.js
Expand Up @@ -55,20 +55,37 @@ exports.run = function(params, opts, callback) {
pack,
inputOptions = opts || {},
options = {},
app;
app,
store;

Y.applyConfig({
useSync: true,
modules: {
'mojito-util': {
fullpath: path.join(__dirname, '../../app/autoload/util.common.js')
},
'mojito-resource-store': {
fullpath: path.join(__dirname, '../../store.server.js')
}
}
});
Y.use('mojito-util', 'mojito-resource-store');

// load details
store = new Y.mojito.ResourceStore({
root: process.cwd(),
context: {}
});

try {
// Are we in a Mojito App? Read the application.json config to find out.
appConfig = Y.JSON.parse(fs.readFileSync(path.join(root,
'application.json'), 'utf8'));
appConfig = appConfig[0];
// Are we in a Mojito App? Read the application config to find out.
appConfig = store.config.readConfigYCB(path.join(root, 'application.json'));
} catch (err) {
appConfig = {};
}

try { // Read the package.json config
pack = Y.JSON.parse(fs.readFileSync(path.join(root, 'package.json'),
'utf8'));
try { // Read the package config
pack = store.config.readConfigSimple(path.join(root, 'package.json'));
} catch (err2) {
pack = {};
}
Expand Down
21 changes: 11 additions & 10 deletions lib/store.server.js
Expand Up @@ -207,7 +207,7 @@ YUI.add('mojito-resource-store', function(Y, NAME) {

this._validDims = this._parseValidDims(this.config.getDimensions());
this.validateContext(this._config.context);
this._fwConfig = this.config.readConfigJSON(this._libs.path.join(this._config.mojitoRoot, 'config.json'));
this._fwConfig = this.config.readConfigSimple(this._libs.path.join(this._config.mojitoRoot, 'config.json'));
this._appConfigStatic = this.getAppConfig({});
},
destructor: function() {},
Expand Down Expand Up @@ -732,7 +732,8 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
ress,
r,
res,
routes;
routes,
routeFile;

for (p = 0; p < routesFiles.length; p += 1) {
path = routesFiles[p];
Expand All @@ -743,11 +744,9 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
fixedPaths[path] = true;
}

ress = this.getResources('server', ctx, {type: 'config'});
for (r = 0; r < ress.length; r += 1) {
res = ress[r];
if (fixedPaths[res.source.fs.fullPath]) {
routes = Y.mojito.util.copy(this.config.readConfigYCB(res.source.fs.fullPath, ctx));
for (routeFile in fixedPaths) {
if (fixedPaths.hasOwnProperty(routeFile)) {
routes = Y.mojito.util.copy(this.config.readConfigYCB(routeFile, ctx));
out = Y.merge(out, routes);
}
}
Expand Down Expand Up @@ -916,7 +915,7 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
parents: [],
dir: dir
};
info.pkg = this.config.readConfigJSON(this._libs.path.join(dir, 'package.json'));
info.pkg = this.config.readConfigSimple(this._libs.path.join(dir, 'package.json'));

if (Object.keys(info.pkg).length) {
mojitoVersion = info.pkg.version;
Expand Down Expand Up @@ -979,9 +978,11 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
if (CONVENTION_SUBDIR_TYPE_IS_JS[type] && '.js' !== fs.ext) {
return false;
}
if ('spec' === type && '.json' !== fs.ext) {

if ('spec' === type && ('.json' !== fs.ext && '.yaml' !== fs.ext && '.yml' !== fs.ext)) {
return false;
}

return {
type: type,
skipSubdirParts: 1
Expand Down Expand Up @@ -1620,7 +1621,7 @@ YUI.add('mojito-resource-store', function(Y, NAME) {
} else {
mojitType = this._libs.path.basename(dir);
}
packageJson = this.config.readConfigJSON(this._libs.path.join(dir, 'package.json'));
packageJson = this.config.readConfigSimple(this._libs.path.join(dir, 'package.json'));
if (packageJson) {
if (packageJson.name) {
mojitType = packageJson.name;
Expand Down

0 comments on commit df6149b

Please sign in to comment.