2 * pkginfo.js: Top-level include for the pkginfo module
4 * (C) 2011, Charlie Robbins
8 var fs = require('fs'),
9 path = require('path');
12 // ### function pkginfo ([options, 'property', 'property' ..])
13 // #### @pmodule {Module} Parent module to read from.
14 // #### @options {Object|Array|string} **Optional** Options used when exposing properties.
15 // #### @arguments {string...} **Optional** Specified properties to expose.
16 // Exposes properties from the package.json file for the parent module on
17 // it's exports. Valid usage:
19 // `require('pkginfo')()`
21 // `require('pkginfo')('version', 'author');`
23 // `require('pkginfo')(['version', 'author']);`
25 // `require('pkginfo')({ include: ['version', 'author'] });`
27 var pkginfo = module.exports = function (pmodule, options) {
28 var args = [].slice.call(arguments, 2).filter(function (arg) {
29 return typeof arg === 'string';
33 // **Parse variable arguments**
35 if (Array.isArray(options)) {
37 // If the options passed in is an Array assume that
38 // it is the Array of properties to expose from the
39 // on the package.json file on the parent module.
41 options = { include: options };
43 else if (typeof options === 'string') {
45 // Otherwise if the first argument is a string, then
46 // assume that it is the first property to expose from
47 // the package.json file on the parent module.
49 options = { include: [options] };
53 // **Setup default options**
55 options = options || {};
57 // ensure that includes have been defined
58 options.include = options.include || [];
60 if (args.length > 0) {
62 // If additional string arguments have been passed in
63 // then add them to the properties to expose on the
66 options.include = options.include.concat(args);
69 var pkg = pkginfo.read(pmodule, options.dir).package;
70 Object.keys(pkg).forEach(function (key) {
71 if (options.include.length > 0 && !~options.include.indexOf(key)) {
75 if (!pmodule.exports[key]) {
76 pmodule.exports[key] = pkg[key];
84 // ### function find (dir)
85 // #### @pmodule {Module} Parent module to read from.
86 // #### @dir {string} **Optional** Directory to start search from.
87 // Searches up the directory tree from `dir` until it finds a directory
88 // which contains a `package.json` file.
90 pkginfo.find = function (pmodule, dir) {
92 dir = path.dirname(pmodule.filename);
95 var files = fs.readdirSync(dir);
97 if (~files.indexOf('package.json')) {
98 return path.join(dir, 'package.json');
102 throw new Error('Could not find package.json up from: ' + dir);
104 else if (!dir || dir === '.') {
105 throw new Error('Cannot find package.json from unspecified directory');
108 return pkginfo.find(pmodule, path.dirname(dir));
112 // ### function read (pmodule, dir)
113 // #### @pmodule {Module} Parent module to read from.
114 // #### @dir {string} **Optional** Directory to start search from.
115 // Searches up the directory tree from `dir` until it finds a directory
116 // which contains a `package.json` file and returns the package information.
118 pkginfo.read = function (pmodule, dir) {
119 dir = pkginfo.find(pmodule, dir);
121 var data = fs.readFileSync(dir).toString();
125 package: JSON.parse(data)
130 // Call `pkginfo` on this module and expose version.
134 include: ['version'],