jonschlinkert / grunt-readme

DEPRECATED. Use Verb instead
https://github.com/assemble/verb
Other
30 stars 10 forks source link

never require grunt - always use the one passed in #44

Closed dylang closed 10 years ago

dylang commented 10 years ago
  // Add custom template delimiters for our templates.
  grunt.template.addDelimiters('readme', '{%', '%}');

This grunt is from var grunt = require('grunt'), not the grunt passed in. This means that its possible two instances of grunt are being used (for example different versions).

I think it's a good coding policy to use the grunt being passed in so that you know any state set will propagate.

Also I think this means grunt should be a peerDependency in the package.json to make sure the versions match up. As it is currently coded, grunt must be a dependency in grunt-readme's package.json, not a devDependency as it is is currently.

For lib files that need grunt, i tend to do something like this:

var util = require('../lib/util')(grunt);
/**
 * Utils
 */

// Node.js
var fs    = require('fs');
var path  = require('path');

// node_modules
var frep  = require('frep');
var _     = require('lodash');

module.exports = function(grunt) {

  function meta (key, obj) {
    if (_.isUndefined(key)) {
        return {};
      } else if (_.isString(obj[key])) {
        return String(obj[key]) || "";
      } else if (_.isObject(obj[key])) {
        return JSON.stringify(obj[key], null, 2) || {};
      } else {
        return null;
      }
    }

    /**
     * Data file reader factory
     * Automatically determines the reader based on extension.
     * Use instead of grunt.file.readJSON or grunt.file.readYAML
     */

    function readData(filepath) {
      var ext = path.extname(filepath);
      var reader = grunt.file.readJSON;
      switch(ext) {
        case '.json':
          grunt.verbose.writeln('>> Reading JSON'.yellow);
          reader = grunt.file.readJSON;
          break;
        case '.yml':
        case '.yaml':
          grunt.verbose.writeln('>> Reading YAML'.yellow);
          reader = grunt.file.readYAML;
          break;
      }
      return reader(filepath);
    }

    /**
     * Data format reader factory (see ./docs/methods.md)
     * Reads in data from a string, object or array
     * Enables all of the following configs to work in task options:
     * (basically throw any data config format and it 'should' work)
     */

    function readOptionsData(data) {
      var metadata;
      if (_.isString(data) || _.isArray(data)) {
        data = Array.isArray(data) ? data : [data];
        data.map(function(val) {
          grunt.verbose.ok('Type:'.yellow, grunt.util.kindOf(val));
          // Skip empty data files to avoid compiler errors
          if (_.isString(val)) {
            grunt.file.expand(val).forEach(function(filepath) {
              var checkForContent = grunt.file.read(filepath);
              if (checkForContent.length === 0 || checkForContent === '') {
                grunt.verbose.warn('Skipping empty path:'.yellow, val);
              } else {
                var parsedData = exports.readData(filepath);
                metadata = grunt.config.process(_.extend({}, metadata, parsedData));
                grunt.verbose.ok('metadata:'.yellow, metadata);
              }
            });
          }
          if (_.isObject(val)) {
            metadata = grunt.config.process(_.extend({}, metadata, val));
            grunt.verbose.ok('metadata:'.yellow, metadata);
          }
        });
      } else if (_.isObject(data)) {
        metadata = data;
      } else {
        metadata = {};
      }
      return metadata;
    }

    /**
     * Compile Lo-Dash templates
     */

    function compileTmpl(src, options, fn) {
      options = options || {};
      var output = grunt.template.process(src, {
        data: options.data || {},
        delimiters: options.delimiters || 'readme'
      });
      return _.isFunction(fn) ? fn(output) : output;
    }

    /**
     * Replacement patterns
     */
    var arr = [
      {
        pattern: /^`#/gm,
        replacement: '#'
      },
      {
        pattern: /\[\%/g,
        replacement: '{%'
      },
      {
        pattern: /\%\]/g,
        replacement: '%}'
      },
      {
        pattern: /^\s*/,
        replacement: ''
      },
      {
        pattern: /\s*\{{!(--)?.+(--)?}}/g,
        replacement: ''
      },
      {
        pattern: /\[\[!/g,
        replacement: '{{!'
      },
      {
        pattern: /\]\]/g,
        replacement: '}}'
      }
    ];

    function frepWithPatterns(str) {
      return frep.strWithArr(str, arr);
    }

    // expose the functions you want to be public
    return {
        meta: meta,
        readData: readData,
        readOptionsData: readOptionsData,
        compileTmpl: compileTmpl,
        frep: frepWithPatterns
    }

};
jonschlinkert commented 10 years ago

I've already refactored this plugin entirely and this was already resolved in the refactor. thanks!

jonschlinkert commented 10 years ago

actually I'll leave this open until I push that up...

dylang commented 10 years ago

oh that's great!

jonschlinkert commented 10 years ago

closing per the comments I made on the previous issue (regarding Verb)