From 7c447bb83bf8fd64df51fa9b3e3bc52843c79469 Mon Sep 17 00:00:00 2001 From: Benjamin Lupton Date: Tue, 7 Aug 2012 10:01:46 +1000 Subject: [PATCH] Nearly there, just need some more testing. --- .gitignore | 1 + .npmignore | 3 -- History.md | 12 ++++++ package.json | 4 +- src/bin/docpad-server.coffee | 5 ++- src/lib/docpad.coffee | 71 ++++++++----------------------- src/lib/interfaces/console.coffee | 31 ++++++++++++-- src/lib/models/document.coffee | 12 +++--- src/lib/plugin-loader.coffee | 14 +++--- src/main.coffee | 3 +- src/test/render.test.coffee | 18 +++++++- 11 files changed, 99 insertions(+), 75 deletions(-) diff --git a/.gitignore b/.gitignore index 8214ca0c..096adb27 100755 --- a/.gitignore +++ b/.gitignore @@ -15,4 +15,5 @@ node_modules npm-debug.log test/out/ +test/render-out/ out/ \ No newline at end of file diff --git a/.npmignore b/.npmignore index 7521ec3f..faba7e06 100755 --- a/.npmignore +++ b/.npmignore @@ -1,7 +1,4 @@ -.DS_Store -.git* .travis* -*.md Makefile src/ diff --git a/History.md b/History.md index cec8897b..facffe4b 100755 --- a/History.md +++ b/History.md @@ -1,5 +1,17 @@ ## History +- v6.5.0 August 3, 2012 + - Can now specify a custom configuration file vis the command line using `-c, --config ` + - Can now specify a custom outPath via the command line using `-o, --out ` + - Can now set template data via `req.templateData` + - Fixed `Document::writeSource` + - The `serverExtend` event will now also emit the `express` dependency if used + - When using the `docpad-server` executable, you can now customise the action via the `DOCPAD_SERVER_ACTION` environment variable + - No longer attempts to install plugins dependencies every time, this is outside the scope of DocPad and in the standard use cases already handled via npm + - No longer accepts `npmPath`, `gitPath`, and `nodePath` as configuration options, instead these should be environment variables at `NPM_PATH`, `GIT_PATH`, and `NODE_PATH` respectively (without the underscore is also acceptable) + - Fixed `require('docpad').createInstance` (was accidentally dropped in v6.2.0) + - Removed markdown files from `.npmignore` as they are now required for the new npm website listing + - v6.4.1 July 19, 2012 - Added new `source` attribute to the file model, as the `content` attribute on the document model is actually the `body` not the original content like it is in the file model diff --git a/package.json b/package.json index 6f7aa628..7ce94a83 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "docpad", - "version": "6.4.1", + "version": "6.5.4", "description": "DocPad is a language agnostic document management system. This means you write your website as documents, in whatever language you wish, and DocPad will handle the compiling, templates and layouts for you. For static documents it will generate static files, for dynamic documents it'll re-render them on each request. You can utilise DocPad by itself, or use it as a module your own custom system. It's pretty cool, and well worth checking out. We love it.", "homepage": "https://github.com/bevry/docpad", "keywords": [ @@ -36,7 +36,7 @@ "npm": ">=1.1.0" }, "dependencies": { - "bal-util": ">=1.12.5 <1.13", + "bal-util": ">=1.13.0 <1.14", "express": "2.5.x", "mime": "1.2.x", "query-engine": ">=1.2.3 <1.3", diff --git a/src/bin/docpad-server.coffee b/src/bin/docpad-server.coffee index 94d037e2..6a469394 100644 --- a/src/bin/docpad-server.coffee +++ b/src/bin/docpad-server.coffee @@ -6,8 +6,11 @@ DocPad.createInstance (err,docpad) -> # Check return console.log(err.stack) if err + # Fetch the server action + serverAction = process.env.DOCPAD_SERVER_ACTION or 'generate server' + # Generate and Serve - docpad.action 'generate server', (err) -> + docpad.action serverAction, (err) -> # Check return console.log(err.stack) if err diff --git a/src/lib/docpad.coffee b/src/lib/docpad.coffee index 7af56f76..798b8dc6 100755 --- a/src/lib/docpad.coffee +++ b/src/lib/docpad.coffee @@ -534,18 +534,6 @@ class DocPad extends EventEmitterEnhanced # ----------------------------- # Other - # NPM Path - # The location of our npm executable - npmPath: null - - # Node Path - # The location of our node executable - nodePath: null - - # Git Path - # The location of our git executable - gitPath: null - # Safe Mode # If enabled, we will try our best to sandbox our template rendering so that they cannot modify things outside of them # Not yet implemented @@ -783,22 +771,6 @@ class DocPad extends EventEmitterEnhanced postTasks = new balUtil.Group (err) => return next(err,@config) - # Get the git path - unless @config.gitPath? - postTasks.push (complete) => - balUtil.getGitPath (err,gitPath) => - return docpad.error(err) if err - @config.gitPath = gitPath - complete() - - # Get the node path - unless @config.nodePath? - postTasks.push (complete) => - balUtil.getNodePath (err,nodePath) => - return docpad.error(err) if err - @config.nodePath = nodePath - complete() - # Initialize postTasks.push (complete) => @loadPlugins(complete) @@ -1125,9 +1097,6 @@ class DocPad extends EventEmitterEnhanced # Init Git Repo # next(err,results) initGitRepo: (opts) -> - # Prepare - opts.gitPath ?= @config.gitPath - # Forward balUtil.initGitRepo(opts) @@ -1138,8 +1107,6 @@ class DocPad extends EventEmitterEnhanced # next(err,results) initNodeModules: (opts={}) -> # Prepare - opts.npmPath ?= @config.npmPath - opts.nodePath ?= @config.nodePath opts.force ?= @config.force opts.output ?= @getDebugging() @@ -1521,12 +1488,12 @@ class DocPad extends EventEmitterEnhanced # Load docpad.log 'debug', "Loading plugin: #{pluginName}" - # Check if it exists + # Check existance loader.exists (err,exists) -> # Error or doesn't exist? return next(err) if err or not exists - # Check if it is supported + # Check support loader.unsupported (err,unsupported) -> # Error? return next(err) if err @@ -1546,26 +1513,22 @@ class DocPad extends EventEmitterEnhanced docpad.log 'warn', "Skipped the unsupported plugin: #{pluginName} due to #{unsupported}" return next() - # It is supported, install its deps - loader.install (err) -> + # Load the class + loader.load (err) -> return next(err) if err - # It is now installed, load it - loader.load (err) -> + # Create an instance + loader.create {}, (err,pluginInstance) -> return next(err) if err - # It is loaded, create it - loader.create {}, (err,pluginInstance) -> - return next(err) if err - - # Add to plugin stores - docpad.loadedPlugins[loader.pluginName] = pluginInstance + # Add to plugin stores + docpad.loadedPlugins[loader.pluginName] = pluginInstance - # Log completion - docpad.log 'debug', "Loaded plugin: #{pluginName}" + # Log completion + docpad.log 'debug', "Loaded plugin: #{pluginName}" - # Forward - return next() + # Forward + return next() # Chain @ @@ -2552,7 +2515,8 @@ class DocPad extends EventEmitterEnhanced # Send dynamic = document.get('dynamic') if dynamic - templateData = docpad.getTemplateData({req,err}) + templateData = balUtil.extend({}, req.templateData or {}, {req,err}) + templateData = docpad.getTemplateData(templateData) document.render {templateData}, (err) -> content = document.get('contentRendered') or document.get('content') or document.getData() if err @@ -2611,9 +2575,10 @@ class DocPad extends EventEmitterEnhanced serverLocation = "http://#{serverHostname}:#{serverPort}/" serverDir = config.outPath docpad.log 'info', "DocPad listening to #{serverLocation} on directory #{serverDir}" - complete() catch err - complete(err) + return complete(err) + finally + return complete() # Plugins docpad.emitSync 'serverBefore', {}, (err) -> @@ -2646,7 +2611,7 @@ class DocPad extends EventEmitterEnhanced # Emit the serverExtend event # So plugins can define their routes earlier than the DocPad routes - docpad.emitSync 'serverExtend', {server}, (err) -> + docpad.emitSync 'serverExtend', {server,express}, (err) -> return next(err) if err # Router Middleware diff --git a/src/lib/interfaces/console.coffee b/src/lib/interfaces/console.coffee index 1f917f24..2e937cf1 100755 --- a/src/lib/interfaces/console.coffee +++ b/src/lib/interfaces/console.coffee @@ -1,5 +1,6 @@ # Requires {cliColor} = require('caterpillar') +pathUtil = require('path') # Console Interface class ConsoleInterface @@ -19,6 +20,14 @@ class ConsoleInterface commander .version(version) + .option( + '-o, --out ' + "where to output the rendered files (to a directory) or file (to an output file)" + ) + .option( + '-c, --config ' + "a custom configuration file to load in" + ) .option( '-e, --env ' "the environment name to use for this instance, multiple names can be separated with a comma" @@ -196,11 +205,21 @@ class ConsoleInterface commanderConfig = @commander sourceConfig = @docpad.initialConfig - # Rename special configuration + # debug -> logLevel if commanderConfig.debug commanderConfig.debug = 7 if commanderConfig.debug is true commanderConfig.logLevel = commanderConfig.debug + # config -> configPaths + if commanderConfig.config + configPath = pathUtil.resolve(process.cwd(),commanderConfig.config) + commanderConfig.configPaths = [configPath] + + # out -> outPath + if commanderConfig.out + outPath = pathUtil.resolve(process.cwd(),commanderConfig.out) + commanderConfig.outPath = outPath + # Apply global configuration for own key, value of commanderConfig if sourceConfig[key]? @@ -274,6 +293,7 @@ class ConsoleInterface # Prepare docpad = @docpad commander = @commander + balUtil = require('bal-util') opts = {} # Prepare filename @@ -290,8 +310,13 @@ class ConsoleInterface renderDocument = -> docpad.action 'render', opts, (err,result) -> return docpad.fatal(err) if err - process.stdout.write(result) - next() + # Path + if commander.out? + balUtil.writeFile(commander.out, result, next) + # Stdout + else + process.stdout.write(result) + next() # Timeout if we don't have stdin timeout = setTimeout( diff --git a/src/lib/models/document.coffee b/src/lib/models/document.coffee index 4d592d50..4d02c7ea 100755 --- a/src/lib/models/document.coffee +++ b/src/lib/models/document.coffee @@ -244,22 +244,22 @@ class DocumentModel extends FileModel # Fetch fullPath = @get('fullPath') content = @get('content') - body = @get('body') - parser = @get('parser') + parser = 'cson' + seperator = '---' # Log file.log 'debug', "Writing the source file: #{fullPath}" # Adjust header = CSON.stringifySync(@meta.toJSON()) - body = body.replace(/^\s+/,'') - content = "### #{parser}\n#{header}\n###\n\n#{body}" + content = body = content.replace(/^\s+/,'') + source = "#{seperator} #{parser}\n#{header}\n#{seperator}\n\n#{body}" # Apply - @set({header,body,content}) + @set({parser,header,body,content,source}) # Write content - balUtil.writeFile fileOutPath, content, (err) -> + balUtil.writeFile fileOutPath, source, (err) -> # Check return next(err) if err diff --git a/src/lib/plugin-loader.coffee b/src/lib/plugin-loader.coffee index ceb91896..9d497972 100755 --- a/src/lib/plugin-loader.coffee +++ b/src/lib/plugin-loader.coffee @@ -164,11 +164,12 @@ class PluginLoader coffee = require('coffee-script') if !coffee and /\.coffee$/.test(@pluginPath) # Load in our plugin @pluginClass = require(@pluginPath)(@BasePlugin) - # Return our plugin - next(null,@pluginClass) catch err # An error occured, return it - next(err,null) + return next(err,null) + + # Return our plugin + next(null,@pluginClass) # Chain @ @@ -184,9 +185,12 @@ class PluginLoader # Create instance with merged configuration docpad = @docpad pluginInstance = new @pluginClass({docpad,config}) - next(null,pluginInstance) catch err - next(err,null) + # An error occured, return it + return next(err,null) + + # Return our instance + return next(null,pluginInstance) # Chain @ diff --git a/src/main.coffee b/src/main.coffee index 552c8405..382ea9b6 100644 --- a/src/main.coffee +++ b/src/main.coffee @@ -5,10 +5,11 @@ fsUtil = require('fs') # Export module.exports = - # Common + # Pre-Defined DocPad: DocPad queryEngine: queryEngine Backbone: Backbone + createInstance: createInstance # Require a local DocPad file require: (relativePath) -> diff --git a/src/test/render.test.coffee b/src/test/render.test.coffee index e08f76e6..d45f4357 100644 --- a/src/test/render.test.coffee +++ b/src/test/render.test.coffee @@ -1,6 +1,5 @@ # RequirestestServer balUtil = require('bal-util') -fs = require('fs') chai = require('chai') expect = chai.expect joe = require('joe') @@ -13,6 +12,7 @@ _ = require('underscore') docpadPath = __dirname+'/../..' rootPath = docpadPath+'/test' renderPath = rootPath+'/render' +outPath = rootPath+'/render-out' expectPath = rootPath+'/render-expected' cliPath = docpadPath+'/bin/docpad' @@ -76,3 +76,19 @@ joe.suite 'docpad-render', (suite,test) -> return done(err) if err expect(stdout).to.equal(input.stdout) done() + + # Works with out path + test 'outPath', (done) -> + input = { + in: '*awesome*' + out: '

awesome

' + outPath: outPath+'/outpath-render.html' + } + balUtil.spawn [cliPath, 'render', 'markdown', '-o', input.outPath], {stdin:input.in, cwd:rootPath}, (err,stdout,stderr,code,signal) -> + return done(err) if err + expect(stdout).to.equal('') + balUtil.readFile outPath+'/outpath-render.html', (err,data) -> + return done(err) if err + result = data.toString() + expect(result).to.equal(input.out) + done()